pallets/flask · error · click.BadParameter

When "--cert" is an SSLContext object, "--key" is not used.

Error message

When "--cert" is an SSLContext object, "--key" is not used.

What it means

Raised by `_validate_key` when `--cert` resolved to an imported `ssl.SSLContext` object and `--key` was also passed. Flask's `--cert` accepts a dotted import path to an SSLContext; such a context already carries its certificate chain and private key (loaded via `load_cert_chain`), so a separate `--key` is meaningless and rejected.

Source

Thrown at src/flask/cli.py:849

    """
    cert = ctx.params.get("cert")
    is_adhoc = cert == "adhoc"

    try:
        import ssl
    except ImportError:
        is_context = False
    else:
        is_context = isinstance(cert, ssl.SSLContext)

    if value is not None:
        if is_adhoc:
            raise click.BadParameter(
                'When "--cert" is "adhoc", "--key" is not used.', ctx, param
            )

        if is_context:
            raise click.BadParameter(
                'When "--cert" is an SSLContext object, "--key" is not used.',
                ctx,
                param,
            )

        if not cert:
            raise click.BadParameter('"--cert" must also be specified.', ctx, param)

        ctx.params["cert"] = cert, value

    else:
        if cert and not (is_adhoc or is_context):
            raise click.BadParameter('Required when using "--cert".', ctx, param)

    return value


class SeparatedPathType(click.Path):

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Drop `--key` and load the key inside the context: call `ctx.load_cert_chain('cert.pem', 'key.pem')` in the module that defines the SSLContext.
  2. Alternatively pass plain file paths instead of a context: `flask run --cert cert.pem --key key.pem`.

Example fix

# before
flask run --cert mymodule:ctx --key key.pem
# after (mymodule.py)
ctx = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER)
ctx.load_cert_chain("cert.pem", "key.pem")
# then: flask run --cert mymodule:ctx
Defensive patterns

Strategy: type-guard

Validate before calling

import ssl
if isinstance(cert, ssl.SSLContext) and key is not None:
    raise SystemExit("SSLContext already contains the key; drop --key")

Type guard

import ssl

def is_ssl_context(obj) -> bool:
    return isinstance(obj, ssl.SSLContext)

Prevention

When it happens

Trigger: `flask run --cert mymodule:ctx --key key.pem` where `mymodule.ctx` is an `ssl.SSLContext` instance; `_ssl_context` import resolution succeeds and `isinstance(cert, ssl.SSLContext)` is true, then the `--key` callback raises.

Common situations: Migrating from file-based cert/key flags to a programmatic SSLContext for custom TLS settings (ciphers, client auth) while leaving the old `--key` flag in a launch script or Procfile.

Related errors


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/9bc5822db436c36c.json. Report an issue: GitHub ↗.