Skip to content

fix: accept absolute unix socket paths in GrpcEndpoint - #1226

Open
Kayvan-Zahiri wants to merge 3 commits into
dapr:mainfrom
Kayvan-Zahiri:unix-socket-absolute-path
Open

Kayvan-Zahiri wants to merge 3 commits into
dapr:mainfrom
Kayvan-Zahiri:unix-socket-absolute-path

Conversation

@Kayvan-Zahiri

Copy link
Copy Markdown

Description

An absolute Unix socket endpoint like unix:///tmp/dapr.sock (or unix:/tmp/dapr.sock) makes GrpcEndpoint raise "paths are not supported for gRPC endpoints", because urlparse puts the socket file path in the URL's path component and _validate_path_and_query rejects any path. unix is listed as an accepted scheme, so this was only usable with relative names like unix:my.sock.

The fix allows a path when the scheme is unix, and builds the hostname from netloc + path. Using netloc + path instead of parsed_url.hostname matters because hostname lowercases, which would point at the wrong file for a name like Dapr-MyApp-grpc.socket.

Since WorkflowRuntime, both DaprWorkflowClients and DaprClient all go through GrpcEndpoint, this fixes all of them, not only the workflow constructors in the issue. Other schemes still reject paths.

Tests: new parser cases (both absolute forms, TLS, mixed case, a bad query), plus a WorkflowRuntime test that reproduces the reported DaprInternalError before the fix. Separately, I checked that grpc connects to a real server over a Unix socket using both targets the parser now produces.

Issue reference

Please reference the issue this PR will close: #1213

Checklist

  • Code compiles correctly
  • Created/updated tests
  • Extended the documentation

unix:///path/to.sock and unix:/path/to.sock put the socket path in the
parsed URL's path, which the path check rejected, so WorkflowRuntime,
DaprWorkflowClient and DaprClient all failed on them. Allow a path for the
unix scheme and build the hostname from netloc + path so the filename's
case is kept.

Signed-off-by: Kayvan Zahiri <kzahiri@dons.usfca.edu>
@Kayvan-Zahiri
Kayvan-Zahiri requested review from a team as code owners September 21, 2026 18:06
@codecov

codecov Bot commented Sep 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 83.90%. Comparing base (fb229bc) to head (e08d60b).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1226   +/-   ##
=======================================
  Coverage   83.89%   83.90%           
=======================================
  Files         123      123           
  Lines       10265    10270    +5     
=======================================
+ Hits         8612     8617    +5     
  Misses       1653     1653           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@CasperGN CasperGN left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, the fix is in the right place and the new tests fail without it. I also confirmed against a real gRPC server that the unix:/abs, unix:///abs and unix:rel targets now connect. A few things before merging:

1. unix://relative/path is now accepted but can never connect.
Before this PR, unix://relative/dir/x.sock failed at parse time with a clear error. Now it passes through unchanged, gRPC logs authority-based URIs not supported by the unix scheme / target uri is not valid, and the client hangs until its timeout. gRPC requires unix:// to be followed by an absolute path. Could you raise a ValueError when the scheme is unix and netloc is non-empty (e.g. "unix:// endpoints require an absolute path; use unix:relative or unix:///absolute"), and add a test for it?
The existing 'unix://my.sock' case in helpers_test.py has the same problem (gRPC rejects it for the same reason). That one predates this PR, but the same check would cover it.

2. Relative socket names are still lowercased.
unix:My.sock still becomes unix:my.sock, because that form has no path and still goes through parsed_url.hostname. Building the hostname from netloc + path for every unix endpoint would make both forms keep their case. Fine as a follow-up if you'd rather keep this PR narrow.

3. Minor, non-blocking:

  • unix:///tmp/x.sock#frag silently drops the fragment. It's harmless, but it's the only part of the address dropped without an error.
  • The deprecated DaprClient.wait() does a TCP connect((hostname, port)), so it can't work with any unix endpoint. This predates the PR; just noting it.

gRPC needs an absolute path after unix://, so unix://my.sock and
unix://rel/dir/x.sock can never connect; raise ValueError instead of
hanging until the timeout. Build the hostname from netloc + path for
every unix endpoint so unix:My.sock keeps its case.

Signed-off-by: Kayvan Zahiri <kzahiri@dons.usfca.edu>
@Kayvan-Zahiri
Kayvan-Zahiri force-pushed the unix-socket-absolute-path branch from da72777 to b563a2a Compare September 25, 2026 16:40
@Kayvan-Zahiri

Copy link
Copy Markdown
Author

Thanks for testing it against a real server. Done in b563a2a:

  1. unix:// with anything before the path (unix://my.sock, unix://relative/dir/x.sock) now raises ValueError with the message you suggested. I changed the two existing unix://my.sock cases to expect the error and added the relative-dir one.
  2. The hostname is now netloc + path for every unix endpoint, so unix:My.sock and unix:run/My.sock keep their case. Added both as cases.

I left the fragment and wait() alone to keep this narrow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[WORKFLOW SDK BUG] Workflow constructors reject Unix-domain socket DAPR_GRPC_ENDPOINT

2 participants