github/spec-kit · error · PresetError

Preset download URL must use HTTPS: {download_url}

Error message

Preset download URL must use HTTPS: {download_url}

What it means

The download_url does not satisfy the HTTPS-or-localhost-HTTP policy enforced by is_https_or_localhost_http (from _download_security). Plain HTTP URLs to remote hosts are rejected to prevent unencrypted, tamperable downloads of preset content.

Source

Thrown at src/specify_cli/presets/__init__.py:4875

        # "https://[::1") makes urlparse / hostname access raise ValueError.
        # The download_url comes from catalog payload data, so surface a clean
        # PresetError rather than leaking a raw ValueError past the command
        # handler (which only catches PresetError). Mirrors catalogs (#3435)
        # and workflows/catalog.py (#3484).
        try:
            parsed = urlparse(download_url)
            hostname = parsed.hostname
            parsed.port
        except ValueError:
            raise PresetError(
                f"Preset download URL is malformed: {download_url}"
            ) from None
        if not hostname:
            raise PresetError(
                f"Preset download URL is malformed: {download_url}"
            )
        if not is_https_or_localhost_http(download_url):
            raise PresetError(
                f"Preset download URL must use HTTPS: {download_url}"
            )

        if target_dir is None:
            target_dir = self.cache_dir / "downloads"
        target_dir = Path(target_dir)
        version = pack_info.get("version", "unknown")
        declared_format = archive_format_from_name(download_url)
        build_safe_download_path(
            target_dir,
            pack_id,
            version,
            error_type=PresetError,
            label="preset",
            suffix=archive_suffix(declared_format or "tar.gz"),
        )
        target_dir.mkdir(parents=True, exist_ok=True)

View on GitHub (pinned to bf88c9f9a8)

Solutions

  1. Serve the artifact over HTTPS and update download_url to the https:// form
  2. For local testing, use http://localhost or http://127.0.0.1 which are explicitly allowed
  3. Ask the catalog maintainer to upgrade their links to HTTPS

Example fix

# before
"download_url": "http://mirror.example.com/mytheme.tar.gz"

# after
"download_url": "https://mirror.example.com/mytheme.tar.gz"
Defensive patterns

Strategy: validation

Validate before calling

from specify_cli._download_security import is_https_or_localhost_http
if not is_https_or_localhost_http(download_url):
    raise ValueError(f"download_url must be HTTPS (or localhost HTTP): {download_url!r}")

Type guard

def is_allowed_scheme_url(url: str) -> bool:
    return url.startswith("https://") or url.startswith("http://localhost") or url.startswith("http://127.0.0.1")

Try / catch

except PresetError as e:
    if "must use HTTPS" in str(e):
        switch_to_https_mirror(download_url)  # or use localhost for tests
    raise

Prevention

When it happens

Trigger: download_url starting with http:// (not https://) and not pointing at localhost — e.g. 'http://example.com/pack.tar.gz' in a third-party catalog entry.

Common situations: Internal mirror served over plain HTTP; legacy catalog entries predating the HTTPS requirement; test fixtures using http URLs for non-localhost hosts.

Related errors


AI-assisted analysis of github/spec-kit@bf88c9f9a8 (2026-08-14). Data as JSON: /api/errors/31aafe6fb655c118. Report an issue: GitHub.