spring-projects/spring-security · error · IllegalArgumentException

method is invalid

Error message

method is invalid

What it means

DPoPProofContext.validate enforces that the HTTP method used to build a DPoP proof is one of the standard HTTP methods (GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE). An IllegalArgumentException is thrown for anything else, since RFC 9449 DPoP proofs only make sense for known HTTP methods. This runs when constructing a DPoP proof JWT context.

Source

Thrown at oauth2/oauth2-jose/src/main/java/org/springframework/security/oauth2/jwt/DPoPProofContext.java:167

			return this;
		}

		/**
		 * Builds a new {@link DPoPProofContext}.
		 * @return a {@link DPoPProofContext}
		 */
		public DPoPProofContext build() {
			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

  1. Normalize the method to uppercase before building the context: method.toUpperCase(Locale.ROOT).
  2. Use only standard HTTP methods defined in the RFC7231 set.
  3. Validate the method against an allow-list before calling the DPoP proof service.
  4. Catch IllegalArgumentException around DPoP proof creation and surface a config error.

Example fix

// before
DPoPProofContext ctx = new DPoPProofContext("get", uri, ...); // throws
// after
DPoPProofContext ctx = new DPoPProofContext("get".toUpperCase(Locale.ROOT), uri, ...);
Defensive patterns

Strategy: validation

Validate before calling

List.of("GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS","TRACE").contains(method.toUpperCase(Locale.ROOT));

Type guard

boolean isValidHttpMethod(String m) {
    return m != null && Set.of("GET","HEAD","POST","PUT","PATCH","DELETE","OPTIONS","TRACE")
        .contains(m.toUpperCase(Locale.ROOT));
}

Prevention

When it happens

Trigger: Creating a DPoPProofContext (via DPoPProofOptions/DPoPProofService) with a method value that is null, empty, lowercase ("get"), or a non-standard method (e.g. "CUSTOM").

Common situations: Passing the HTTP method from a framework that returns it in a different case, a custom REST method, or forgetting to normalize user/config-supplied input before building the proof.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/f4c5e69dcbd1a15e. Report an issue: GitHub.