mlflow/mlflow · error · UsageError

--static-prefix should not end with a '/'.

Error message

--static-prefix should not end with a '/'.

What it means

Raised as click UsageError by _validate_static_prefix when the --static-prefix value ends with '/'. MLflow normalizes prefix joining internally, so a trailing slash would produce double-slash URLs; the CLI rejects it to keep path composition deterministic. The message mirrors the check directly.

Source

Thrown at mlflow/cli/__init__.py:363

            "Security middleware parameters (--allowed-hosts, --cors-allowed-origins, "
            "--disable-security-middleware) are only supported with "
            "the default uvicorn server. They cannot be used with --gunicorn-opts or "
            "--waitress-opts. To use security features, run without specifying a server "
            "option (uses uvicorn by default) or explicitly use --uvicorn-opts."
        )


def _validate_static_prefix(ctx, param, value):
    """
    Validate that the static_prefix option starts with a "/" and does not end in a "/".
    Conforms to the callback interface of click documented at
    http://click.pocoo.org/5/options/#callbacks-for-validation.
    """
    if value is not None:
        if not value.startswith("/"):
            raise UsageError("--static-prefix must begin with a '/'.")
        if value.endswith("/"):
            raise UsageError("--static-prefix should not end with a '/'.")
        if "{" in value or "}" in value:
            raise UsageError("--static-prefix must not contain '{' or '}'.")
    return value


@cli.command(short_help="Run the MLflow tracking server (UI + REST API).")
@click.pass_context
@click.option(
    "--backend-store-uri",
    envvar="MLFLOW_BACKEND_STORE_URI",
    metavar="PATH",
    default=None,
    help="URI to which to persist experiment and run data. Acceptable URIs are "
    "SQLAlchemy-compatible database connection strings "
    "(e.g. 'sqlite:///path/to/file.db') or local filesystem URIs "
    "(e.g. 'file:///absolute/path/to/directory'). By default, data is logged to a local "
    "SQLite database (sqlite:///mlflow.db), falling back to the ./mlruns directory when an "
    "existing ./mlruns store is present.",

View on GitHub (pinned to 6a27f2decc)

Solutions

  1. Strip the trailing slash, e.g. --static-prefix /mlflow
  2. Sanitize the value in deployment scripts (e.g. `PREFIX=${PREFIX%/}`) before invoking the CLI

Example fix

# before
mlflow server --static-prefix /mlflow/

# after
mlflow server --static-prefix /mlflow
Defensive patterns

Strategy: validation

Validate before calling

prefix = raw_prefix.rstrip("/") or "/"

Try / catch

try:
    validate_fn(ctx, param, value)
except click.UsageError as e:
    if "end with a '/'" in str(e):
        value = value.rstrip("/")
        validate_fn(ctx, param, value)
    else:
        raise

Prevention

When it happens

Trigger: Running `mlflow server --static-prefix /mlflow/` (trailing slash).

Common situations: Copy-pasting a URL path with a trailing slash from browser or proxy config; shell autocomplete or heredoc accidentally appending '/'.

Related errors


AI-assisted analysis of mlflow/mlflow@6a27f2decc (2026-08-29). Data as JSON: /api/errors/8e2d71fae0f178dc. Report an issue: GitHub.