ansible/ansible · error · AnsibleError

Collections requirement 'source' entry should contain a vali

Error message

Collections requirement 'source' entry should contain a valid Galaxy API URL but it does not: {not_url!s} is not an HTTP URL.

What it means

Raised in Requirement.from_requirement_dict (lib/ansible/galaxy/dependency_resolution/dataclasses.py) when a galaxy-type requirement's 'source' resolved to a GalaxyAPI object whose api_server is not an HTTP(S) URL. The Galaxy API client is only usable over HTTP, so a non-http api_server (e.g. a hostname, file path, or malformed string) is rejected.

Source

Thrown at lib/ansible/galaxy/dependency_resolution/dataclasses.py:457

                'one of file, galaxy, git, dir, subdirs, or url.'
            )

        if req_name is None and req_type == 'galaxy':
            raise AnsibleError(
                'Collections requirement entry should contain '
                "the key 'name' if it's requested from a Galaxy-like "
                'index server.',
            )

        if req_type != 'galaxy' and req_source is None:
            req_source, req_name = req_name, None

        if (
                req_type == 'galaxy' and
                isinstance(req_source, GalaxyAPI) and
                not _is_http_url(req_source.api_server)
        ):
            raise AnsibleError(
                "Collections requirement 'source' entry should contain "
                'a valid Galaxy API URL but it does not: {not_url!s} '
                'is not an HTTP URL.'.
                format(not_url=req_source.api_server),
            )

        if (
                req_type == 'dir'
                and isinstance(req_source, str)
                and req_source.endswith(os.path.sep)
        ):
            req_source = req_source.rstrip(os.path.sep)

        tmp_inst_req = cls(req_name, req_version, req_source, req_type, req_signature_sources)

        if req_type not in {'galaxy', 'subdirs'} and req_name is None:
            req_name = art_mgr.get_direct_collection_fqcn(tmp_inst_req)  # TODO: fix the cache key in artifacts manager?

View on GitHub (pinned to 9cf16a4aca)

Solutions

  1. Give the server URL a full scheme: `https://galaxy.ansible.com/` in ansible.cfg or requirements source
  2. Verify with `ansible-galaxy collection list --server <url>` that the URL is accepted
  3. In API code, ensure GalaxyAPI is constructed with api_server including http:// or https://

Example fix

# ansible.cfg before
[galaxy]
server.0.url=galaxy.ansible.com

# after
[galaxy]
server.0.url=https://galaxy.ansible.com/
Defensive patterns

Strategy: validation

Validate before calling

from urllib.parse import urlparse

def validate_galaxy_server(url):
    scheme = urlparse(url).scheme
    if scheme not in ('http', 'https'):
        raise SystemExit(f'{url}: Galaxy server URL must start with http:// or https://')

Type guard

def is_http_url(url: str) -> bool:
    p = urlparse(url or '')
    return p.scheme in ('http', 'https') and bool(p.netloc)

Prevention

When it happens

Trigger: Constructing requirements where 'source' is passed as a GalaxyAPI instance programmatically, or via CLI config where the server URL lacks a scheme (`galaxy.ansible.com` instead of `https://galaxy.ansible.com`), causing _is_http_url(req_source.api_server) to fail.

Common situations: ansible.cfg [galaxy] server list entries missing the scheme; custom tooling building GalaxyAPI('https://' stripped) objects; typos like 'htp://'; proxies rewriting configs.

Related errors


AI-assisted analysis of ansible/ansible@9cf16a4aca (2026-08-15). Data as JSON: /api/errors/f258c64abaf1f1ea. Report an issue: GitHub.