_save_prefixes_txt crashes with DoesNotExist when two domains produce identical prefixes.txt

Open
#557 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@git-hyagi is already working on this.

Since Oct 27, 2026.

  • #558 by @git-hyagi — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
57/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
django, python
Domain
backend, databases

Research direction

Start with MavenMetadata in pulp_maven/app/models.py and compare its global sha256 uniqueness with the domain-scoped constraints. Then read _save_prefixes_txt and _save_metadata_content in pulp_maven/app/tasks/__init__.py and check for existing tests around metadata generation. Done means identical metadata content across domains no longer causes DoesNotExist during modify_repo.

Written by the indexing model from the issue text.

Description

Issue

Description

_save_prefixes_txt crashes with MavenMetadata.DoesNotExist when two domains generate a prefixes.txt with identical content (same sha256). This makes modify_repo unusable on the second domain.

Root cause

MavenMetadata.sha256 has a global unique=True constraint (not scoped to _pulp_domain):

# pulp_maven/app/models.py
sha256 = models.CharField(max_length=64, null=False, unique=True, db_index=True)

In _save_prefixes_txt, the save-or-get pattern assumes the IntegrityError came from the domain-scoped unique_together constraint, but it actually comes from the global sha256 uniqueness:

# pulp_maven/app/tasks/__init__.py, line ~83-103
metadata_content = MavenMetadata(
    group_id="", artifact_id="", version=None,
    filename=PREFIXES_TXT_FILENAME,
    sha256=artifact.sha256,
    _pulp_domain=pulp_domain,
)
try:
    with transaction.atomic():
        metadata_content.save()
except IntegrityError:
    metadata_content = MavenMetadata.objects.get(
        group_id="", artifact_id="", version=None,
        filename=PREFIXES_TXT_FILENAME,
        sha256=artifact.sha256,
        _pulp_domain=pulp_domain,  # <-- filters by THIS domain
    )

When domain A and domain B produce prefixes.txt with identical content:

  1. Domain A's .save() succeeds — sha256 is new globally.
  2. Domain B's .save() raises IntegrityError — sha256 already exists (from domain A).
  3. Domain B's .get() filters by _pulp_domain=B, but the record belongs to domain A → DoesNotExist.

The same pattern exists in _save_metadata_content (line ~518-529), which is vulnerable to the same bug for any metadata file that happens to have identical content across domains.

How to reproduce

  1. In a multi-domain Pulp instance, create a Maven repository in domain A.
  2. Upload a single artifact with group_id="org.example" and call modify_repo to add it. This succeeds and generates a prefixes.txt containing only /org/example.
  3. In domain B, create a Maven repository and upload an artifact with the same group_id="org.example".
  4. Call modify_repo on domain B → crashes with MavenMetadata matching query does not exist.

Traceback

File ".../pulpcore/app/tasks/repository.py", line 259, in add_and_remove
    with repository.new_version(base_version=base_version) as new_version:
File ".../pulpcore/app/models/repository.py", line 1513, in __exit__
    repository.finalize_new_version(self)
File ".../pulp_maven/app/models.py", line 639, in finalize_new_version
    self._generate_metadata(new_version)
File ".../pulp_maven/app/models.py", line 1045, in _generate_metadata
    prefixes_pks = _save_prefixes_txt(current_prefixes, self.pulp_domain)
File ".../pulp_maven/app/tasks/__init__.py", line 96, in _save_prefixes_txt
    metadata_content = MavenMetadata.objects.get(
django.core.exceptions.ObjectDoesNotExist: MavenMetadata matching query does not exist.

Suggested fix

Either:

  1. Scope the sha256 uniqueness to the domain — replace the global unique=True on the sha256 field with inclusion in the unique_together constraint (which already includes _pulp_domain).

  2. Handle the cross-domain collision in the fallback — when the IntegrityError is from the global sha256 constraint, look up the existing record without the sha256 filter and update it, or share the content record across domains.

Dominant language
Python
Stars
5
Forks
30
Avg merge
1d 16h
Merged PRs (30d)
26

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from pulp/pulp_maven

All issues in pulp/pulp_maven

Similar issues

More Python issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.