quarkusio/quarkus · error · ConfigurationException

The "From" header must always be included to the list of hea

Error message

The "From" header must always be included to the list of headers to sign.

What it means

DKIM signing of a chosen header list must always include the From header per DKIM semantics. If dkim.signed-headers is provided and none of its entries equals "from" (case-insensitively), Mailers rejects the configuration with this ConfigurationException.

Source

Thrown at extensions/mailer/runtime/src/main/java/io/quarkus/mailer/runtime/Mailers.java:221

            vertxDkimOptions
                    .setHeaderCanonAlgo(CanonicalizationAlgorithm.valueOf(optionsConfig.headerCanonAlgo().get().toString()));
        }

        if (optionsConfig.privateKey().isPresent()) {
            vertxDkimOptions.setPrivateKey(optionsConfig.privateKey().get());
        } else if (optionsConfig.privateKeyPath().isPresent()) {
            vertxDkimOptions.setPrivateKeyPath(optionsConfig.privateKeyPath().get());
        }

        if (optionsConfig.signatureTimestamp().isPresent()) {
            vertxDkimOptions.setSignatureTimestamp(optionsConfig.signatureTimestamp().get());
        }

        if (optionsConfig.signedHeaders().isPresent()) {
            List<String> headers = optionsConfig.signedHeaders().get();

            if (headers.stream().noneMatch(header -> header.equalsIgnoreCase("from"))) {
                throw new ConfigurationException(
                        "The \"From\" header must always be included to the list of headers to sign.");
            }

            vertxDkimOptions.setSignedHeaders(headers);
        }

        return vertxDkimOptions;
    }

    private io.vertx.ext.mail.MailConfig toVertxMailConfig(String name, MailerRuntimeConfig config,
            TlsConfigurationRegistry tlsRegistry) {
        io.vertx.ext.mail.MailConfig cfg = new io.vertx.ext.mail.MailConfig();
        if (config.authMethods().isPresent()) {
            cfg.setAuthMethods(config.authMethods().get());
        }
        cfg.setDisableEsmtp(config.disableEsmtp());
        cfg.setHostname(config.host());
        cfg.setKeepAlive(config.keepAlive());

View on GitHub (pinned to e1c734241f)

Solutions

  1. Add "from" to the signed-headers list, e.g. quarkus.mailer.dkim.signed-headers=from,to,subject,date.
  2. Check casing/whitespace of entries — the comparison is case-insensitive but the value must still literally contain "from".
  3. If unsure which headers to sign, remove dkim.signed-headers and let the library/Vert.x use defaults.

Example fix

// before
quarkus.mailer.dkim.signed-headers=to,subject,date

// after
quarkus.mailer.dkim.signed-headers=from,to,subject,date
Defensive patterns

Strategy: validation

Validate before calling

List<String> signedHeaders = List.of("to", "subject", "date"); // from config
if (signedHeaders.stream().noneMatch(h -> h.equalsIgnoreCase("from"))) {
    throw new IllegalStateException("dkim.signed-headers must include 'from'");
}

Try / catch

try {
    mailer.send(mail).await().indefinitely();
} catch (ConfigurationException e) {
    if (e.getMessage().contains("From\" header")) {
        LOG.error("Add 'from' to quarkus.mailer.dkim.signed-headers", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Configuring quarkus.mailer.dkim.signed-headers as a list that omits From, e.g. signed-headers=to,subject,date, when the mailer config is built.

Common situations: Copying a signed-headers list from another provider's docs that excludes From; splitting headers incorrectly so "From" ends up outside the list; tooling generating headers alphabetically and dropping From.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/2dfcd9a7bfbe1ed7. Report an issue: GitHub.