In SPDX 2.3, PackageDownloadLocation is a mandatory field. For a Git source, write the scheme and transport together, such as git+https, then the repository URL, an at sign and a pinned revision, and a hash sign if you need a subpath. If there is no location, write NONE. If you cannot tell, write NOASSERTION.
Why this field is mandatory
Unlike supplier or originator, download location must appear exactly once in every package. The spec states the intent plainly: where and how to download the exact package being referenced is critical verification and tracking data. A reader should be able to fetch what you built from.
The field accepts a plain URL, a version control system (VCS) location, NONE, or NOASSERTION. NONE means there is no download location whatsoever. NOASSERTION covers cases where you tried and could not decide, made no attempt, or deliberately gave no information.
The VCS format
The spec gives this general shape: the VCS tool and transport, then host name, then optional path to the repository, then an optional revision after an at sign, then an optional subpath after a hash sign.
PackageDownloadLocation: git+https://git.example.org/MyProject.git@refs/tags/v1.0
PackageDownloadLocation: git+https://git.example.org/MyProject@da39a3ee5e6b4b0d3255bfef95601890afd80709#lib/variable.rb
PackageDownloadLocation: NOASSERTION
The supported Git schemes in the spec are git, git+git, git+https, git+http and git+ssh. Mercurial uses hg+ prefixes, Subversion uses svn, and Bazaar is mentioned too.
Pin it, and pin it unambiguously
A branch name moves. A tag can be moved. A commit hash does not change. The spec recommends specifying a branch name, commit hash, revision or tag, and for Git it recommends the unambiguous refs/heads/ or refs/tags/ form instead of a bare name, to prevent shadowing problems, where a branch and a tag share a name.
| Pin style | Example | Stability |
|---|---|---|
| Branch | @main | Moves on every commit |
| Bare tag | @v1.0 | Ambiguous if a branch has the same name |
| Full tag ref | @refs/tags/v1.0 | Clear, but tags can be re-pointed |
| Commit hash | @da39a3ee... | Fixed |
What not to put in it
Credentials. The spec says user names and passwords in the host name are not supported and should be treated as an error. Access control belongs outside the SBOM.
Client-local forms. The spec says the scp style form with an at sign and colon, and forms using regular expressions, should not be used.
A homepage. The download location is for fetching the package, not reading about it. There is a separate home page field.
A habit for build tools
Make the generator write the exact commit it built, not the branch name you asked for. If your pipeline checks out a tag, resolve it to a hash at build time and record both in the source information field. That way an SBOM stays truthful after the tag moves.
Safeguard can generate SBOMs and run dependency scanning across your repositories, so the fields discussed here are checked on real projects instead of by hand. You can try the free scan at gold.safeguard.sh/scan.
Try it yourself
Open the demo, click through the component list, and look at how each package is identified and what is missing.
Click through it at your own pace, or open it full screen.
Quick check
What do I write if the package was built from an internal repo?
Use the VCS form with your internal URL if the SBOM stays internal. If you share it externally and do not want to expose the host, discuss with your security team whether to use NOASSERTION.
Is PackageDownloadLocation optional?
No. In SPDX 2.3.1 it is required, once per package, and the value can be NONE or NOASSERTION.
Sources
Last reviewed: 19 October 2026.