Skip to content

Fails to Authenticate When Exporting Models (BasicAuth Missing)Β #222

@andrasKelle

Description

@andrasKelle

Summary

When exporting registered models using the mlflow-export-import tool against a standard MLflow Tracking Server secured with Basic Authentication, the export fails with:

401 Unauthorized β€” You are not authenticated.

This happens even though experiments and runs export successfully, and environment variables
MLFLOW_TRACKING_USERNAME and MLFLOW_TRACKING_PASSWORD are set correctly.

The root cause is that BasicAuth credentials are never included in the HTTP requests used for model registry operations.


Root Cause Analysis

Model export uses the internal HttpClient class:

mlflow_export_import/client/http_client.py

This client adds only Bearer tokens to requests:

def _mk_headers(self):
    headers = { "User-Agent": USER_AGENT, "Content-Type": "application/json" }
    if self.token:
        headers["Authorization"] = f"Bearer {self.token}"
    return headers

However:

  • Standard MLflow servers typically use BasicAuth
  • The client does not look at environment variables:
    • MLFLOW_TRACKING_USERNAME
    • MLFLOW_TRACKING_PASSWORD
  • Result: model registry API calls (registered-models/get, etc.) are unauthenticated.

Experiments still work because the high-level MlflowClient handles BasicAuth, but the export tool bypasses it and sends raw HTTP requests.


Reproduction

1. Configure MLflow server with BasicAuth

(e.g., using nginx / ingress auth)

2. Set environment variables:

export MLFLOW_TRACKING_URI=http://127.0.0.1:8080
export MLFLOW_TRACKING_USERNAME=test
export MLFLOW_TRACKING_PASSWORD=test1234

3. Run model export:

python mlflow_export.py --export-full-model Demo_IrisModel

4. Result:

401 Unauthorized
GET /api/2.0/mlflow/registered-models/get?name=Demo_IrisModel

Expected Behavior

The export tool should authenticate using BasicAuth when username and password are set in the environment.


Actual Behavior

HttpClient never attaches BasicAuth headers, only Bearer tokens, causing 401 errors for:

  • Registered model lookup
  • Model version listing
  • Model metadata retrieval

Proposed Fix

Modify _mk_headers() in http_client.py to add BasicAuth support:

def _mk_headers(self):
    headers = {
        "User-Agent": USER_AGENT,
        "Content-Type": "application/json",
    }

    # 1. Databricks token
    if self.token:
        headers["Authorization"] = f"Bearer {self.token}"
        return headers

    # 2. BasicAuth for standard MLflow servers
    username = os.getenv("MLFLOW_TRACKING_USERNAME")
    password = os.getenv("MLFLOW_TRACKING_PASSWORD")

    if username and password:
        import base64
        raw = f"{username}:{password}"
        encoded = base64.b64encode(raw.encode()).decode("utf-8")
        headers["Authorization"] = f"Basic {encoded}"

    return headers

Why this works

  • MLflow already supports BasicAuth for normal usage
  • Model export bypasses MLflow client β†’ must send auth headers manually
  • This patch restores proper authentication for all registry API calls

Additional Notes

  • This bug affects all model export flows, including incremental or full exports.
  • Experiments may export correctly, making the issue misleading.
  • Fix is backward compatible and does not affect Databricks use cases.

Request

Please review and merge the proposed fix.
If preferred, I can open a pull request with the patch included.

Thanks for maintaining this highly valuable tool! πŸ™Œ

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions