justauth/JustAuth · error · AuthException
5015
5015
Error message
Invalid client secret
What it means
AuthException with AuthResponseStatus.ILLEGAL_CLIENT_SECRET (code 5015) from AuthAppleRequest.checkConfig: config.getClientSecret() is empty. For Apple this field must hold the .p8 private key content — JustAuth itself builds the JWT client secret from it in getToken().
Source
Thrown at src/main/java/me/zhyd/oauth/request/AuthAppleRequest.java:102
// https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_rest_api/authenticating_users_with_sign_in_with_apple#3383773
return AuthUser.builder()
.rawUserInfo(object)
.uuid(object.getString("sub"))
.email(object.getString("email"))
.username(authToken.getUsername())
.token(authToken)
.source(source.toString())
.build();
}
@Override
protected void checkConfig(AuthConfig config) {
super.checkConfig(config);
if (StringUtils.isEmpty(config.getClientId())) {
throw new AuthException(AuthResponseStatus.ILLEGAL_CLIENT_ID, source);
}
if (StringUtils.isEmpty(config.getClientSecret())) {
throw new AuthException(AuthResponseStatus.ILLEGAL_CLIENT_SECRET, source);
}
if (StringUtils.isEmpty(config.getKid())) {
throw new AuthException(AuthResponseStatus.ILLEGAL_KID, source);
}
if (StringUtils.isEmpty(config.getTeamId())) {
throw new AuthException(AuthResponseStatus.ILLEGAL_TEAM_ID, source);
}
}
/**
* 获取token
* @see <a href="https://developer.apple.com/documentation/accountorganizationaldatasharing/creating-a-client-secret">creating-a-client-secret</a>
* @return jwt token
*/
private String getToken() {
return Jwts.builder().header().add(AbstractJwk.KID.getId(), this.config.getKid()).and()
.issuer(this.config.getTeamId())
.subject(this.config.getClientId())View on GitHub (pinned to 694bbf1b01)
Solutions
- Paste the full contents of the .p8 key (including BEGIN/END PRIVATE KEY lines) into clientSecret
- If loading from a file/vault, read it into the string at startup before building AuthConfig
- Do not confuse clientSecret (.p8 PEM) with kid (key identifier) or teamId
Example fix
// before
.clientSecret("/etc/keys/AuthKey_ABC123.p8")
// after
String pem = new String(Files.readAllBytes(Path.of("/etc/keys/AuthKey_ABC123.p8")), UTF_8);
AuthConfig.builder().clientSecret(pem)... Defensive patterns
Strategy: validation
Validate before calling
String pem = config.getClientSecret();
if (StringUtils.isEmpty(pem) || !pem.contains("BEGIN PRIVATE KEY")) {
throw new IllegalStateException("APPLE clientSecret must be the .p8 PEM content");
} Prevention
- Store the .p8 PEM as a whole unit (base64 in env vars or multiline secrets)
- Do not put file paths or key ids into clientSecret
- Automate .p8 loading from your secret manager at startup
When it happens
Trigger: Constructing AuthAppleRequest without clientSecret, or with a path to the .p8 file instead of the file's PEM content.
Common situations: Developer put the file path or key id into clientSecret instead of the PEM body; the .p8 content loaded with escaped newlines (\n literals) making it 'present' but unusable — here it must merely be non-empty, but empty values fail this check; secret managed via vault and not injected.
Related errors
AI-assisted analysis of justauth/JustAuth@694bbf1b01 (2026-08-14).
Data as JSON: /api/errors/ad719b52698e6c24.
Report an issue: GitHub.