cryptomator/cryptomator · error · IOException
Failed to parse JWE
Error message
Failed to parse JWE
What it means
ReceiveKeyController.receivedLegacyAccessTokenSuccess parses a raw legacy access token as a JWEObject; a ParseException (token not valid compact JWE serialization) is rethrown as IOException("Failed to parse JWE"). The token delivered by the legacy Hub flow could not be structurally parsed.
Source
Thrown at src/main/java/org/cryptomator/ui/keyloading/hub/ReceiveKeyController.java:297
case 402 -> licenseExceeded();
case 403 -> accessNotGranted();
case 410 -> accessGoneVaultArchived();
case 404 -> needsLegacyDeviceRegistration();
default -> throw new IOException("Unexpected response " + response.statusCode());
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
@Deprecated
private void receivedLegacyAccessTokenSuccess(String rawToken) throws IOException {
try {
var token = JWEObject.parse(rawToken);
result.complete(ReceivedKey.legacyDeviceKey(token));
window.close();
} catch (ParseException e) {
throw new IOException("Failed to parse JWE", e);
}
}
private void licenseExceeded() {
window.setScene(invalidLicenseScene.get());
}
@Deprecated
private void needsLegacyDeviceRegistration() {
window.setScene(legacyRegisterDeviceScene.get());
}
private void accessNotGranted() {
window.setScene(unauthorizedScene.get());
}
private void accessGoneVaultArchived() {
window.close();View on GitHub (pinned to af99135172)
Solutions
- Log/inspect the raw token's first characters — it should start with five dot-separated Base64URL segments
- Verify the Hub server actually supports the legacy token flow being used; upgrade client or server to matching versions
- Retry the key-receive flow to get a fresh token
- Check for proxies/URL handlers mangling the token before it reaches the controller
Example fix
// before
catch (ParseException e) { throw new IOException("Failed to parse JWE", e); }
// after: fail with diagnostics
catch (ParseException e) {
LOG.error("token not JWE: {}...", rawToken.substring(0, Math.min(20, rawToken.length())));
throw new IOException("Failed to parse JWE", e);
} Defensive patterns
Strategy: validation
Validate before calling
static boolean looksLikeJwe(String token) {
return token != null && token.chars().filter(c -> c == '.').count() == 4;
} Type guard
static boolean isParseableJwe(String raw) { try { JWEObject.parse(raw); return true; } catch (ParseException e) { return false; } } Try / catch
try { receivedLegacyAccessTokenSuccess(rawToken); } catch (IOException e) { showInvalidTokenScene(); LOG.error("token not JWE", e.getCause()); } Prevention
- Check token shape (5 dot-separated segments) before parsing
- Retry the flow to obtain a fresh token on parse failure
- Ensure the Hub server's legacy flow is enabled and version-compatible
When it happens
Trigger: The legacy access token string handed to receivedLegacyAccessTokenSuccess (via receivedLegacyAccessTokenResponse) is empty, HTML (e.g. an error page), truncated, or otherwise not in JWE compact serialization, causing JWEObject.parse to throw ParseException.
Common situations: Hub server returning an error page instead of the token, legacy flow interrupted producing partial token, copy/paste or clipboard corruption of the token, Hub version emitting a plain JWT where a JWE is expected.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Expected JWE payload to be JSON
- Unexpected JWE payload
- Server answered with unparsable user key
- Authorization returned status code
- Failed to load keypair
AI-assisted analysis of cryptomator/cryptomator@af99135172 (2026-09-05).
Data as JSON: /api/errors/66998113d8a2ffc2.
Report an issue: GitHub.