SourceConnectionError using local video against Docker inference server

Project Type: Object Detection

Operating System & Browser: Windows 11 Pro & Chrome Version 141.0.7390.77

Workspace/Project ID: main-epy5a/bird-id-dipgw

Hello all,

I just started using Roboflow and am new to computer vision in general, but I’m a software developer, so it’s embarrassing that I’m sure this is a very simple oversight.

I’m trying to just do object detection with a specialized model that picks up hummingbirds better than the stock object detection models do with generic “bird” matches.

I’ve trained a model that works, I’ve tested it in the web browser with images and it works.

I’m trying to use a local inference server in Docker to run against. So… I installed Docker, made sure the desktop version had CUDA and WSL 2, per this page: GPU support | Docker Docs. The benchmarks work fine, seemingly, the GPU is available to Docker.

I have a Python 3 project running in IntelliJ using just a standard virtualenv and pip. I installed the following packages for the project:

google-cloud-videointelligence
inference
inference-sdk
inference-gpu
inference-cli
ultralytics
supervision

I started the inference server using the regular “inference server start” and it booted up in a Docker container.

I know my Roboflow API key is working because I have a script that invokes a workflow using my model with “InferencePipeline.init_with_workflow” and it works just fine.

However, I followed the general instructions on this page to try to run an inference pipeline on my Docker container, it looks something like this:

from inference_sdk import InferenceConfiguration, InferenceHTTPClient

MODEL_ID = "bird-id-dipgw/5"
# the following path definitely exists on my local machine.
video_path = r'C:\Users\<my username>\Videos\test video 003.mp4'
config = InferenceConfiguration(confidence_threshold=0.5, iou_threshold=0.5)
client = InferenceHTTPClient(
    api_url="http://localhost:9001",
    api_key=API_KEY,
)
client.configure(config)
client.select_model(MODEL_ID)

pipeline_data = client.start_inference_pipeline_with_workflow(
    video_reference=video_path,
    workflow_id="bird-flow-1",
    workspace_name="main-epy5a",
    # workflows_thread_pool_workers=16, # tried this with 4 and 16, no diff
)

pipeline_id = pipeline_data['context']['pipeline_id']
print(f"pipeline ID = {pipeline_id}")
for i in range(10):  #this is temp, "while True" eventually locks up the server.
    print("pipelines...")
    pprint(client.list_inference_pipelines())
    print("status...")
    pprint(client.get_inference_pipeline_status(pipeline_id))
    print("results...")
    pprint(client.consume_inference_pipeline_result(pipeline_id))

This pipeline basically fails out of the gate because it gives “SourceConnectionError”:

{‘context’: ‘inference_pipeline’,
‘event_type’: ‘INFERENCE_ERROR’,
‘payload’: {‘error_context’: ‘inference_thread’,
‘error_message’: 'Cannot ’
'connect ’
'to ’
'video ’
'source ’
'under ’
'reference: ’
'C:\Users\\Videos\’
'\test ’
'video ’
‘003.mp4’,
‘error_type’: ‘SourceConnectionError’},
‘severity’: 40,
‘timestamp’: ‘2025-10-18T20:13:35.690396’},

So, I don’t know what is ultimately SUPPOSED to happen when this HTTPs client runs.

The documentation clearly states you can reference local web streams OR files for the video_reference component.

However, I feel like there’s a POST limit you’d run into if you select a really large video for this kind of thing, so IDK if it’s actually trying to encode and upload the video in the body, it seems like NOT when I look at the API at on my local Docker container at port 9001.

I also thought, ok well maybe you have to upload the video to the inference server running in Docker, but the API locally doesn’t seem to have the same Roboflow upload API that allows uploading files.

I feel like I’m missing something obvious, but I know they say “object inference on videos locally is experimental” but I would hope that doesn’t mean “doesn’t work at all.”

Hey! I’m admittedly a rookie at this, but while you wait for the pros to troubleshoot, I thought I’d offer up my two cents.

I got inference working on a video locally using Docker. And I’m not a pro by any means so it’s definitely better than “experimental”. I looked at my working project and have two ideas you could start with.

  1. Try to put the video file in the same directory as the python script (you can see I have just the video reference with no path needed). I feel like I had that same problem when I first started.

  2. The instructions you reference show an inference version of 0.21.0 and the current version is at 0.58.0, so maybe you’re just dealing with some really outdated code.

My pipeline code is below, but I think you already did something like this with your init_with_workflow you mentioned. However, you seem to imply you ran that without Docker and now you are trying a version with Docker. I did my init_with_workflow with Docker for the video run using a workflow. I partially referenced this link (with a live stream example) so you could check this out and see if it helps: Realtime Video Stream Analysis with Computer Vision

Best of luck!

pipeline = InferencePipeline.init_with_workflow(

api_key=RAK,

workspace_name="my-name",

workflow_id="keypointzoneonly", 

video_reference="bridge.mkv", # Path to video, device id (int, usually 0 for built in webcams), or RTSP stream url

max_fps=30,

on_prediction=my_sink

)

1 Like

Hi! Thank you for the reply!

Yeah, the documentation is maybe out of date, but the API still seems to be similar enough for the latest version that I don’t see anything obvious that would have changed my script.

I did try moving (and even re-naming to make simpler) the video I wanted to process, but it seems to have the same effect.

I have not had time to debug this since I last posted, but still looking for suggestions.

Got it working. Python script at the bottom. Hope this gets it done for you as well!

TLDR - had to mount the video in the Docker container so it could be “seen”. Spun up a “server” (container) in a PowerShell window via the docker command (which also mounts the video in the container.) Then ran the script in a separate PowerShell window. (Also, a while ago I had to do a bunch of work to get my old GPU working with CUDA and Docker, and that’s what I use for inference which is why I need the GPU image of the inference server. I think this works for you too since you mentioned having the GPU running.)

Updates to your Python code:

  • added check for API key (not required)
  • put in my own model and workspace info so remove those and use yours (which I tried to leave in comments)
  • set video path to /videos/bridge.mkv which is where I mounted my local folder into the Docker container
  • put in a check for outputs to break the polling loop early if we get results for testing

Process to set up container and run script:

1. Kill old containers so they’re not holding the port or the same container name:

docker ps -a

docker stop <old_container_name>

docker rm <old_container_name>

2. In a NEW PowerShell window, set your Roboflow API key for THIS session:

$env:ROBOFLOW_API_KEY = <YOUR_KEY_HERE>

(You can confirm with: echo $env:ROBOFLOW_API_KEY)

3. Start the inference server container manually (don’t use `inference server start` here).

IMPORTANT:

- Use --gpus all if you’re using the GPU image.

- Map your local video folder into /videos in the container.

- Expose port 9001 so your Python client can hit it.

- Pass your API key into the container with -e.

Example (this is mine, change the path before the colon):

docker run --name inference --gpus all -p 9001:9001 \`

-e ROBOFLOW_API_KEY=$env:ROBOFLOW_API_KEY \`

-v C:\\Users\\<middle_of_the_path>\\<folder_with_video_file>:/videos \`

roboflow/roboflow-inference-server-gpu:latest

Notes:

- The left side of -v is my Windows folder that contains bridge.mkv.

- The right side (/videos) is where that folder will appear INSIDE the container.

- Leave this PowerShell window OPEN. It will log stuff like

“Uvicorn running on http://0.0.0.0:9001” and some scheduler warnings. That’s normal.

4. Open a SECOND PowerShell window.

In that second window, run the Python script above.

- Make sure ROBOFLOW_API_KEY is also set in THIS window, or the script will complain.

- The script talks to http://localhost:9001

- The script passes video_reference=“/videos/yourfile.mkv”

(this matches the IN-CONTAINER path, not your Windows path)

  1. You should see:

    • pipeline_id get printed

    • status changing to INITIALISING then RUNNING

    • source_properties with fps, width, height, total_frames

    • eventually non-empty “outputs” in the results poll.

Sample output I got:
…gApNi+lFFAC0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFJsX0oooAWiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigBNi+lAUA5AoooAWiiigAooooAKKKKAAgHg0mxfSiigA2L6UbF9KKKAAKAcgUtFFABRRRQAUUUUAFFFFABRRRQAUhUE5IoooAUADgUUUUAFFFFAH/2Q==',
‘video_metadata’: {‘comes_from_video_file’: True,
‘fps’: 60.0,
‘frame_number’: 1,
‘frame_timestamp’: ‘2025-07-21T20:56:04.037195’,
‘measured_fps’: 60.0,
‘video_identifier’: ‘default_source’}},
‘model_predictions’: {‘image’: {‘height’: 1080, ‘width’: 1920},
‘predictions’: [{‘class’: ‘vehicle’,
‘class_id’: 0,
‘confidence’: 0.9250530004501343,
‘detection_id’: ‘df643c8f-6359-4d52-ad20-23c538f41eae’,
‘height’: 125.0,
‘keypoints’: [{‘class’: ‘rear’,
‘class_id’: 0,
‘confidence’: 0.9996968507766724,
‘x’: 1064.0,
‘y’: 585.0},
{‘class’: ‘front’,

Python Script

from inference_sdk import InferenceConfiguration, InferenceHTTPClient

import os

from pprint import pprint

import time




# NEW SECTION grab the api_key from the environment variable 

RAK = os.getenv("ROBOFLOW_API_KEY") 

if not RAK: 

    raise ValueError("ROBOFLOW_API_KEY is not set in the environment.") 





#OLDMODEL_ID = "bird-id-dipgw/5"

MODEL_ID = "vehicle_heading/1"

# the following path definitely exists on my local machine.

#OLD_DONOTUSE video_path = r'C:\Users\<my username>\Videos\test video 003.mp4'

video_path="/videos/bridge.mkv" #UPDATE this changing bridge.mkv to your file name but leave /videos/ in place

config = InferenceConfiguration(confidence_threshold=0.5, iou_threshold=0.5)

client = InferenceHTTPClient(

    api_url="http://localhost:9001",

    #OLDapi_key=API_KEY,

    api_key=RAK

)

client.configure(config)

client.select_model(MODEL_ID)




pipeline_data = client.start_inference_pipeline_with_workflow(

    video_reference=video_path,

    #OLDworkflow_id="bird-flow-1",

    workflow_id="keypointorientation",

    #OLDworkspace_name="main-epy5a",

    workspace_name="manufacturing-n8ggq",

    # workflows_thread_pool_workers=16, # tried this with 4 and 16, no diff

)




pipeline_id = pipeline_data['context']['pipeline_id']

print(f"pipeline ID = {pipeline_id}")

for i in range(30):  #this is temp, "while True" eventually locks up the server.

    print("pipelines...")

    pprint(client.list_inference_pipelines())

    print("status...")

    pprint(client.get_inference_pipeline_status(pipeline_id))

    #updated results as a variable to reuse for the output print below

    results = client.consume_inference_pipeline_result(pipeline_id)

    print("results...")

    pprint(results)

    print(f"\n--- poll {i} ---")




    # helpful indicator: if we got any outputs, stop early

    if results.get("outputs"):

        print("Got model outputs ✅")

        break




    time.sleep(0.5)  # give the server breathing room

Oh man, that’s so above and beyond. I had a suspicion that I had to expose the video to the container itself, which makes sense but definitely is not contained in the instructions/wiki or anything AFAICT.

I appreciate the effort, I think Roboflow should consider updating the docs with this kind of flow. I will give it a go and report back but I’m sure that’s it.

1 Like