{"record":{"id":"194946af1b6f719f","repo":"spring-projects/spring-security","slug":"oauth-2-0-parameter-parametername","errorCode":null,"errorMessage":"OAuth 2.0 Parameter: + parameterName","messagePattern":"OAuth 2\\.0 Parameter: \\+ parameterName","errorType":"error_code","errorClass":"OAuth2AuthenticationException","httpStatus":400,"severity":"error","filePath":"oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceAuthorizationRequestAuthenticationProvider.java","lineNumber":220,"sourceCode":"\t */\n\tpublic void setDeviceCodeGenerator(OAuth2TokenGenerator<OAuth2DeviceCode> deviceCodeGenerator) {\n\t\tAssert.notNull(deviceCodeGenerator, \"deviceCodeGenerator cannot be null\");\n\t\tthis.deviceCodeGenerator = deviceCodeGenerator;\n\t}\n\n\t/**\n\t * Sets the {@link OAuth2TokenGenerator} that generates the {@link OAuth2UserCode}.\n\t * @param userCodeGenerator the {@link OAuth2TokenGenerator} that generates the\n\t * {@link OAuth2UserCode}\n\t */\n\tpublic void setUserCodeGenerator(OAuth2TokenGenerator<OAuth2UserCode> userCodeGenerator) {\n\t\tAssert.notNull(userCodeGenerator, \"userCodeGenerator cannot be null\");\n\t\tthis.userCodeGenerator = userCodeGenerator;\n\t}\n\n\tprivate static void throwError(String errorCode, String parameterName) {\n\t\tOAuth2Error error = new OAuth2Error(errorCode, \"OAuth 2.0 Parameter: \" + parameterName, ERROR_URI);\n\t\tthrow new OAuth2AuthenticationException(error);\n\t}\n\n\tprivate static final class OAuth2DeviceCodeGenerator implements OAuth2TokenGenerator<OAuth2DeviceCode> {\n\n\t\tprivate final StringKeyGenerator deviceCodeGenerator = new Base64StringKeyGenerator(\n\t\t\t\tBase64.getUrlEncoder().withoutPadding(), 96);\n\n\t\t@Override\n\t\tpublic @Nullable OAuth2DeviceCode generate(OAuth2TokenContext context) {\n\t\t\tif (context.getTokenType() == null\n\t\t\t\t\t|| !OAuth2ParameterNames.DEVICE_CODE.equals(context.getTokenType().getValue())) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tInstant issuedAt = Instant.now();\n\t\t\tInstant expiresAt = issuedAt\n\t\t\t\t.plus(context.getRegisteredClient().getTokenSettings().getDeviceCodeTimeToLive());\n\t\t\treturn new OAuth2DeviceCode(this.deviceCodeGenerator.generateKey(), issuedAt, expiresAt);\n\t\t}","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/oauth2/oauth2-authorization-server/src/main/java/org/springframework/security/oauth2/server/authorization/authentication/OAuth2DeviceAuthorizationRequestAuthenticationProvider.java#L202-L238","documentation":"Helper throwError() builds an OAuth2Error whose description is 'OAuth 2.0 Parameter: <parameterName>' and throws it as an OAuth2AuthenticationException. It is the provider's generic way of rejecting device authorization requests with missing/invalid request parameters (e.g. missing client_id or scope per RFC 8628).","triggerScenarios":"authenticate() validating the device authorization request: a required OAuth 2.0 parameter (such as client_id or scope) is absent or invalid; throwError(errorCode, parameterName) is invoked with that parameter name.","commonSituations":"Device clients sending malformed POSTs to /oauth2/device_authorization (missing client_id, wrong content-type, parameters in the wrong place); custom authentication converters dropping parameters; clients sending unsupported scope values.","solutions":["Fix the device client request: send all required parameters (client_id, scope if configured) as application/x-www-form-urlencoded form parameters.","Return the error code/description from the OAuth2AuthenticationException response body to the client so it can correct the request.","If you wrote a custom authentication converter for the device authorization endpoint, ensure it extracts the same parameters the default one does.","Verify registeredClient scopes match what the device client requests."],"exampleFix":"// before\ncurl -X POST https://as.example.com/oauth2/device_authorization  # no params\n// after\ncurl -X POST https://as.example.com/oauth2/device_authorization \\\n  -d \"client_id=device-client\" -d \"scope=device.scope\"","handlingStrategy":"validation","validationCode":"Objects.requireNonNull(clientId, \"client_id is required\");\nif (scope != null && !scope.matches(\"[\\x20-\\x7E]+\")) {\n    throw new IllegalArgumentException(\"Invalid scope parameter\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    return deviceAuthorizationEndpoint.process(converter.convert(request));\n} catch (OAuth2AuthenticationException e) {\n    return ResponseEntity.badRequest().body(Map.of(\n        \"error\", e.getError().getErrorCode(),\n        \"error_description\", e.getError().getDescription()));\n}","preventionTips":["Send device authorization requests as application/x-www-form-urlencoded with client_id and scope.","Reuse the official client SDK parameter names (OAuth2ParameterNames) rather than ad-hoc keys.","Log the full parameter set of rejected requests to spot converter/parameter mismatches early."],"tags":["oauth2","device-flow","request-parameter","validation"],"backgroundTag":"invalid-query-parameter","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}