rust-lang/cargo · error

source ID should have valid URLs

Error message

source ID should have valid URLs

What it means

Invariant in lockfile source-id encoding: `encodable_source_id` builds a `TomlLockfileSourceId` from `id.as_encoded_url()` / `id.as_url()` and calls `.expect("source ID should have valid URLs")`. The constructor validates the URL string; cargo assumes every non-path `SourceId` has a URL that serializes cleanly.

Source

Thrown at src/resolver/encode.rs:673

    }
    TomlLockfilePackageId {
        name: id.name().to_string(),
        version,
        source,
    }
}

fn encodable_source_id(id: SourceId, version: ResolveVersion) -> Option<TomlLockfileSourceId> {
    if id.is_path() {
        None
    } else {
        Some(
            if version >= ResolveVersion::V4 {
                TomlLockfileSourceId::new(id.as_encoded_url().to_string())
            } else {
                TomlLockfileSourceId::new(id.as_url().to_string())
            }
            .expect("source ID should have valid URLs"),
        )
    }
}

View on GitHub (pinned to 0e07a15537)

Solutions

  1. Inspect `[patch]`/`[source]`/git dependency URLs in `Cargo.toml` for unusual characters; URL-encode or fix them.
  2. Reproduce with `cargo generate-lockfile -v` to see which source triggers encoding.
  3. Report a cargo bug with the source URL and lockfile format version.

Example fix

// before
TomlLockfileSourceId::new(id.as_url().to_string()).expect("source ID should have valid URLs")

// after
TomlLockfileSourceId::new(id.as_url().to_string())
    .with_context(|| format!("source `{}` has a URL unfit for the lockfile", id.as_url()))?
Defensive patterns

Strategy: validation

Validate before calling

// Before generating a lockfile, validate all source URLs serialize cleanly.
for sid in sources {
    let s = sid.as_url().to_string();
    if url::Url::parse(&s).is_err() {
        return Err(anyhow!("source {} has an invalid URL", s));
    }
}

Prevention

When it happens

Trigger: Encoding a `Cargo.lock` when a source's URL fails `TomlLockfileSourceId::new`'s validation — e.g. a git/source URL containing characters the lockfile schema rejects, or an internal `SourceId` with an empty/invalid URL.

Common situations: A git dependency with an unusual URL (spaces, control chars); a `[source]` replacement or `[patch]` with a malformed URL; a cargo bug constructing a `SourceId` without a URL; very rare for crates.io-style registries.

Related errors


AI-assisted analysis of rust-lang/cargo@0e07a15537 (2026-08-06). Data as JSON: /data/errors/5a4fb33752e7c511.json. Report an issue: GitHub.