jwtk/jjwt · error · EncodingException

Unable to encode input: ${e.getMessage()}

Error message

Unable to encode input: ${e.getMessage()}

What it means

ExceptionPropagatingEncoder adapts any Encoder implementation to JJWT's Encoder contract. Its encode method rethrows EncodingException unchanged, but if the delegate encoder throws any other Exception (e.g. IOException writing to a stream), it wraps it in an EncodingException with 'Unable to encode input: ...'. The original exception remains available via getCause().

Source

Thrown at api/src/main/java/io/jsonwebtoken/io/ExceptionPropagatingEncoder.java:57

    /**
     * Encoded the specified  data, delegating to the wrapped Encoder, wrapping any
     * non-{@link EncodingException} as an {@code EncodingException}.
     *
     * @param t the data to encode
     * @return the encoded data
     * @throws EncodingException if there is an unexpected problem during encoding.
     */
    @Override
    public R encode(T t) throws EncodingException {
        Assert.notNull(t, "Encode argument cannot be null.");
        try {
            return this.encoder.encode(t);
        } catch (EncodingException e) {
            throw e; //propagate
        } catch (Exception e) {
            String msg = "Unable to encode input: " + e.getMessage();
            throw new EncodingException(msg, e);
        }
    }
}

View on GitHub (pinned to fb71496164)

Solutions

  1. Inspect getCause() for the delegate encoder's real failure and fix that root cause
  2. Check that the input to encode is non-null and of the expected type for the encoder
  3. If you implemented a custom Encoder, catch internal failures and throw EncodingException from encode() so they propagate without wrapping
  4. Use the built-in Encoders (Base64/Base64Url) or verify your encoder setup and JJWT module versions are consistent

Example fix

// before
public byte[] doEncode(Object o) throws IOException {
    return mapper.writeValueAsBytes(o); // raw exception -> Unable to encode input
}

// after
public byte[] doEncode(Object o) {
    try {
        return mapper.writeValueAsBytes(o);
    } catch (JsonProcessingException e) {
        throw new EncodingException("Unable to encode object", e);
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Java: guard input before encoding
boolean isEncodableInput(Object in) {
    return in != null && !(in instanceof String s && s.isEmpty())
        && !(in instanceof byte[] b && b.length == 0);
}

Type guard

boolean isEncoderInput(Object in) {
    return in instanceof String || in instanceof byte[];
}

Try / catch

try {
    String token = Jwts.builder().setClaims(claims).signWith(key).compact();
} catch (EncodingException e) {
    Throwable root = e.getCause();
    // non-null cause = delegate encoder threw an unexpected exception
}

Prevention

When it happens

Trigger: Any JJWT operation that encodes data (JwtBuilder.compact() encoding header/payload/signature, key or byte encoding via Encoders/Encoder-based APIs) where the underlying encoder throws a non-EncodingException — a raw IOException, RuntimeException, or a custom encoder's unexpected failure.

Common situations: A custom Encoder writing to a closed or failing stream (IOException); passing null or an unsupported input type to an encoder that does not guard against it; third-party serialization inside a custom encoder throwing unchecked exceptions; version mismatches between JJWT modules causing unexpected encoder behavior.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/1c2316f5fec5ecfd. Report an issue: GitHub.