spring-projects/spring-security · error · IllegalArgumentException
targetUri must be a valid URL
Error message
targetUri must be a valid URL
What it means
DPoPProofContext.validate parses the targetUri and requires it to be convertible to a java.net.URL. If new URI(...) fails or URI.toURL() fails (missing scheme, invalid characters, unknown protocol), an IllegalArgumentException with this message is thrown. DPoP proofs must bind to a well-formed absolute HTTP(S) URI.
Source
Thrown at oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/DPoPProofContext.java:175
Assert.hasText(this.method, "method cannot be empty");
Assert.hasText(this.targetUri, "targetUri cannot be empty");
validate();
return new DPoPProofContext(this.dPoPProof, this.method, this.targetUri, this.accessToken);
}
private void validate() {
if (!"GET".equals(this.method) && !"HEAD".equals(this.method) && !"POST".equals(this.method)
&& !"PUT".equals(this.method) && !"PATCH".equals(this.method) && !"DELETE".equals(this.method)
&& !"OPTIONS".equals(this.method) && !"TRACE".equals(this.method)) {
throw new IllegalArgumentException("method is invalid");
}
URI uri;
try {
uri = new URI(this.targetUri);
uri.toURL();
}
catch (Exception ex) {
throw new IllegalArgumentException("targetUri must be a valid URL", ex);
}
if (uri.getQuery() != null || uri.getFragment() != null) {
throw new IllegalArgumentException("targetUri cannot contain query or fragment parts");
}
}
}
}
View on GitHub (pinned to 96852e8860)
Solutions
- Pass an absolute URI including scheme, e.g. https://auth.example.com/oauth2/token.
- Validate the URI at startup: new URI(uri).toURL() in a try-catch before use.
- If you only have a path, prepend the configured issuer base URL.
- Prefer building the URI with UriComponentsBuilder.fromHttpUrl(...) to fail early with a clearer message.
Example fix
// before
new DPoPProofContext("POST", "/oauth2/token", ...); // throws
// after
new DPoPProofContext("POST", "https://server.example.com/oauth2/token", ...); Defensive patterns
Strategy: validation
Validate before calling
URI uri = URI.create(targetUri); uri.toURL(); // throws MalformedURLException if not a valid absolute URL
Type guard
boolean isAbsoluteHttpUrl(String s) {
try {
URL u = new URI(s).toURL();
return "http".equals(u.getProtocol()) || "https".equals(u.getProtocol());
} catch (Exception e) { return false; }
} Prevention
- Always store full absolute token/resource endpoint URLs in configuration.
- Validate configured URIs at application startup, not at proof-creation time.
- Build URIs with UriComponentsBuilder.fromHttpUrl to fail with clearer errors.
- Avoid concatenating base URLs and paths without trailing-slash normalization.
When it happens
Trigger: Constructing a DPoPProofContext with a targetUri that is relative (e.g. "/path"), lacks a scheme ("example.com/path"), uses an unknown scheme, or contains characters illegal in a URL.
Common situations: Passing only the path/endpoint portion instead of the full URL from configuration, environment-specific config with a typo, or user-supplied token-endpoint URLs that were not validated at startup.
Understand the failure class
Background: "Invalid URL" / "URL cannot be empty": fix the malformed or missing URL behind request-construction failures — this error's family across 50 libraries.
Related errors
- targetUri cannot contain query or fragment parts
- method is invalid
- invalid_dpop_proof
- Unsupported alg parameter in JWS Header: ${algorithm.getName
- Missing jwk parameter in JWS Header.
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/3a6ebdf7440d4eaf.
Report an issue: GitHub.