kestra-io/kestra · error · PebbleException

Unsupported content type

Error message

Unsupported content type 

What it means

Thrown by the 'http' function's fallback MessageBodyWriter when the requested contentType has no registered Micronaut writer and is not YAML. The fallback writer only knows how to emit YAML, so any other unregistered content type (or a body type with no matching writer) lands here.

Source

Thrown at core/src/main/java/io/kestra/core/runners/pebble/functions/HttpFunction.java:53

import jakarta.inject.Provider;
import jakarta.inject.Singleton;

@Singleton
public class HttpFunction<T> implements KestraFunction {
    public static final String NAME = "http";

    private final MessageBodyWriter<T> FALLBACK_CONTENT_WRITER = (type, mediaType, object, outgoingHeaders, outputStream) ->
    {
        if (mediaType == MediaType.APPLICATION_YAML_TYPE || mediaType.equals(MediaType.of("application/yaml"))) {
            try {
                outputStream.write(JacksonMapper.ofYaml().writeValueAsString(object).getBytes(StandardCharsets.UTF_8));
                return;
            } catch (IOException e) {
                throw new PebbleException(e, "Couldn't write the request body as YAML");
            }
        }

        throw new PebbleException(new IllegalArgumentException("Unsupported content type: " + mediaType), "Unsupported content type ");
    };

    @Inject
    private DefaultMessageBodyHandlerRegistry defaultMessageBodyHandlerRegistry;

    @Inject
    private Provider<RunContextFactory> runContextFactoryProvider;

    @Override
    public Object execute(Map<String, Object> args, PebbleTemplate self, EvaluationContext context, int lineNumber) {
        throwIfMissingArgs(args, self, lineNumber);

        EvaluationContextImpl evaluationContext = (EvaluationContextImpl) context;
        Map<String, Object> pebbleVariables = evaluationContext.getScopeChain().getGlobalScopes().stream()
            .flatMap(scope -> scope.getKeys().stream())
            .distinct()
            .collect(HashMap::new, (m, k) -> m.put(k, context.getVariable(k)), HashMap::putAll);

View on GitHub (pinned to 823fada927)

Solutions

  1. Use a contentType with a registered writer — 'application/json' (default) or 'application/yaml'.
  2. Correct typos in the contentType string (e.g. 'aplication/json').
  3. If you truly need a custom content type, pre-format the body as a string and pass contentType 'text/plain'.
  4. Register a custom Micronaut MessageBodyWriter for the MIME type if it must be a first-class type.

Example fix

// before
{{ http(uri, method='POST', body=payload, contentType='text/csv') }}
// after
{{ http(uri, method='POST', body=payload, contentType='application/json') }}
Defensive patterns

Strategy: validation

Validate before calling

{% set ct = contentType ?? 'application/json' %}{% if ct not in ['application/json', 'application/yaml'] %}{% set ct = 'application/json' %}{% endif %}{{ http(uri, method='POST', body=payload, contentType=ct) }}

Prevention

When it happens

Trigger: Calling http(..., body=<obj>, contentType='text/csv') (or 'application/xml', 'application/octet-stream', etc.) where Micronaut's DefaultMessageBodyHandlerRegistry has no writer for that type+body-class combination.

Common situations: Using a niche or custom MIME type, a typo in the contentType string, or expecting the function to auto-convert to a format Micronaut does not ship a writer for.

Related errors


AI-assisted analysis of kestra-io/kestra@823fada927 (2026-08-14). Data as JSON: /api/errors/230e6d4da5f11ac0. Report an issue: GitHub.