karatelabs/karate · error · RuntimeException

unexpected 'configure' key

Error message

unexpected 'configure' key: '${key}'

What it means

Karate's 'configure' is strict: only a known set of keys is accepted, and any unrecognized key hits the switch's default branch which throws listing the bad key. This is intentional so that config key typos fail loudly instead of being silently ignored.

Solutions

  1. Check the key spelling against the supported configure keys in the current docs
  2. Replace 'configure <channel> = ...' with karate.channel('<channel>') or boot.ext('<channel>') configuration
  3. For logging-related settings use 'configure logging = { ... }' instead of legacy keys like 'report' or 'logLevel'
  4. Consult docs/MIGRATION_GUIDE.md if the key worked in an older Karate version

Example fix

// before
* configure kafka = { servers: 'localhost:9092' }
// after
* def channel = karate.channel('kafka', { servers: 'localhost:9092' })
Defensive patterns

Strategy: validation

Validate before calling

// check key against the supported set before configuring
var allowed = ['ssl','logging','report','driver','retry', /* ...supported keys */];
if (allowed.indexOf(key) === -1) { throw 'unsupported configure key: ' + key; }

Type guard

null

Try / catch

try { karate.configure(key, value); } catch (RuntimeException e) { if (e.getMessage().contains("unexpected 'configure' key")) { log.error('Check supported configure keys / migration guide'); } throw e; }

Prevention

When it happens

Trigger: Calling configure with a misspelled or unsupported key, e.g. "configure foo = true", or using a channel-style key like "configure kafka = ..." which is explicitly not allowed — channels are configured via karate.channel()/boot.ext() rich JS objects instead.

Common situations: Migrating from older Karate versions where more configure keys existed; typos like 'loggging' or 'loggin'; attempting 'configure grpc = ...' or 'configure kafka = ...' when the new API requires karate.channel('kafka'); copying config from outdated docs.

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 karatelabs/karate@a22eb90246 (2026-09-12). Data as JSON: /api/errors/351e5f13f7d15a6a. Report an issue: GitHub.

Appendix: source

Thrown at karate-core/src/main/java/io/karatelabs/core/KarateConfig.java:458

            case "printEnabled" -> {
                logger.warn("configure 'printEnabled' is deprecated; print/karate.log go to the 'karate.scenario' "
                        + "SLF4J category - set its level to WARN in logback.xml to keep them off the console, "
                        + "or 'configure logging = {{ console: \"warn\" }}' to quiet all karate console output");
            }
            case "lowerCaseResponseHeaders" -> {
                logger.warn("configure 'lowerCaseResponseHeaders' is deprecated; "
                        + "'match header X' is already case-insensitive and 'karate.lowerCase(responseHeaders)' "
                        + "covers direct map access");
            }
            case "logModifier" -> {
                logger.warn("configure 'logModifier' is removed; "
                        + "use the declarative form: 'configure logging = {{ mask: {{ headers: [...], jsonPaths: [...], patterns: [...] }} }}'");
            }

            // No channel-type cases: channels (grpc, kafka, …) are configured via their rich
            // JS object — karate.channel('kafka') / the boot.ext('kafka') object — not via global
            // 'configure <type>'. 'configure' stays strict so key typos fail loudly.
            default -> throw new RuntimeException("unexpected 'configure' key: '" + key + "'");
        }
    }

    private void configureSsl(Object value) {
        if (value == null) {
            this.ssl.clear();
            return;
        }
        if (value instanceof Boolean b) {
            this.ssl.clear();
            this.ssl.put("enabled", b);
            this.ssl.put("trustAll", true);
            return;
        }
        if (value instanceof String s) {
            this.ssl.clear();
            this.ssl.put("enabled", true);
            this.ssl.put("algorithm", s);

View on GitHub (pinned to a22eb90246)