Skip to content

core: throw IOException when ProxySelector returns null or empty list#12793

Merged
kannanjgithub merged 1 commit into
grpc:masterfrom
mfperminov:add-check-for-proxies-empty-list
May 22, 2026
Merged

core: throw IOException when ProxySelector returns null or empty list#12793
kannanjgithub merged 1 commit into
grpc:masterfrom
mfperminov:add-check-for-proxies-empty-list

Conversation

@mfperminov
Copy link
Copy Markdown
Contributor

@mfperminov mfperminov commented May 4, 2026

ProxySelector.select(URI) is contractually required to return a non-null,
non-empty list. Some implementations violate this, which previously caused
an opaque crash in ProxyDetectorImpl:

java.lang.IndexOutOfBoundsException: Index: 0
    at java.util.Collections$EmptyList.get
    at io.grpc.internal.ProxyDetectorImpl.detectProxy

Detect this case explicitly and throw an IOException naming the offending
ProxySelector class, so a broken implementation can be identified and
fixed by its author rather than silently worked around in every caller.

@linux-foundation-easycla
Copy link
Copy Markdown

linux-foundation-easycla Bot commented May 4, 2026

CLA Signed

The committers listed above are authorized under a signed CLA.

  • ✅ login: mfperminov / name: Mikhail Perminov (ac43fae)

@mfperminov mfperminov force-pushed the add-check-for-proxies-empty-list branch 4 times, most recently from da37275 to ac43fae Compare May 4, 2026 21:25
@mfperminov
Copy link
Copy Markdown
Contributor Author

Hi @ejona86, would you be the right person to review this small proxy detection fix?

@ejona86
Copy link
Copy Markdown
Member

ejona86 commented May 13, 2026

Can we identify the broken Android deployments? I know we can't fix them, but we can document what software we are working around. The Java API says there will always be entries in the list, so both null and empty list are invalid. I'd normally suggest we fail (cleanly, not like it is now) instead of ignoring the API breakage.

@mfperminov
Copy link
Copy Markdown
Contributor Author

Can we identify the broken Android deployments? I know we can't fix them, but we can document what software we are working around. The Java API says there will always be entries in the list, so both null and empty list are invalid. I'd normally suggest we fail (cleanly, not like it is now) instead of ignoring the API breakage.

Thanks for the context.
I unfortunately cannot provide detailed production/device information because of NDA. The only information I can share is that, in our production crash reports, more than 90% of the occurrences are on Android 14 devices, across multiple manufacturers.
Given that the Java API contract requires the returned list to be non-empty, I understand your concern about silently treating this as "no proxy".
If I understand your suggestion correctly, the preferred direction would be to fail explicitly and add a comment explaining the workaround/behavior, e.g. replace the current accidental IndexOutOfBoundsException with a clearer exception such as IllegalStateException when ProxySelector returns an empty list.
Is that the approach you would prefer for this PR?

@ejona86
Copy link
Copy Markdown
Member

ejona86 commented May 13, 2026

So I've looked around some, and I don't see any other reports of something like this. I'm very suspicious, as Android 14 is plenty old enough for us to have heard of this problem. It is seeming more likely at this point that maybe you have a broken ProxySelector configured somewhere in your app.

How does this sound: Add in checks for null/isEmpty(), and throw an IOException with the classname of the ProxySelector as part of the error string. I know exception strings are often discarded on Android, but this has no semantic concerns and would help anyone that accidentally writes a broken ProxySelector. Ideally the ProxySelector would get fixed, instead of all callers working around it.

If we find out this behavior is widespread we would re-evaluate the approach.

@kannanjgithub
Copy link
Copy Markdown
Contributor

@mfperminov are you planning to add the debug info suggested?

@mfperminov
Copy link
Copy Markdown
Contributor Author

@mfperminov are you planning to add the debug info suggested?

Yes, I’ll add the suggested debug info today.

@mfperminov mfperminov force-pushed the add-check-for-proxies-empty-list branch from ac43fae to 05ead32 Compare May 22, 2026 10:06
ProxySelector.select(URI) is contractually required to return a non-null,
non-empty list. Some implementations violate this, which previously caused
an opaque crash in ProxyDetectorImpl:

  java.lang.IndexOutOfBoundsException: Index: 0
    at java.util.Collections$EmptyList.get
    at io.grpc.internal.ProxyDetectorImpl.detectProxy

Detect this case explicitly and throw an IOException naming the offending
ProxySelector class, so a broken implementation can be identified and
fixed by its author rather than silently worked around in every caller.
@mfperminov mfperminov force-pushed the add-check-for-proxies-empty-list branch from 05ead32 to b76589c Compare May 22, 2026 11:58
@mfperminov
Copy link
Copy Markdown
Contributor Author

@ejona86 @kannanjgithub
made an update

@kannanjgithub
Copy link
Copy Markdown
Contributor

/gcbrun

@ejona86 ejona86 added the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label May 22, 2026
@grpc-kokoro grpc-kokoro removed the kokoro:run Add this label to a PR to tell Kokoro the code is safe and tests can be run label May 22, 2026
@ejona86 ejona86 changed the title core: handle empty proxy selector result core: throw IOException when ProxySelector returns null or empty list May 22, 2026
@mfperminov
Copy link
Copy Markdown
Contributor Author

The macOS Kokoro failure appears to be an infrastructure/Homebrew issue before
the build starts:

brew install --cask temurin@8 failed with
Error: undefined method 'first' for nil.

Could anyone please rerun the macOS presubmit?

@kannanjgithub
Copy link
Copy Markdown
Contributor

We are yet to fix the macOS build, it happens on all PRs.

@kannanjgithub kannanjgithub merged commit 4111f6f into grpc:master May 22, 2026
17 of 18 checks passed
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.

4 participants