Create a STAC catalog: troubleshooting guide
This troubleshooting guide explains how to diagnose and fix common failures when creating a SpatioTemporal Asset Catalog (STAC). It focuses on the boundary between a valid JSON document and a usable catalog: correct Catalog, Collection, and Item structure; resolvable links; stable identifiers; spatial and temporal metadata; asset definitions; extensions; and recursive validation. The examples use PySTAC and ordinary JSON inspection so you can isolate whether a problem comes from the STAC object itself, its file layout, or the data assets it describes.
A STAC catalog is not merely a directory of imagery files with a JSON wrapper. It is a linked set of JSON resources that lets software discover, interpret, and traverse spatiotemporal assets. A Catalog organizes links to child Catalogs, Collections, and Items; a Collection adds metadata such as spatial and temporal extents, license, providers, and summaries; and an Item describes one or more assets with a GeoJSON footprint, time information, links, and asset metadata. (stacspec.org) Most catalog failures occur because one of those layers is being treated as interchangeable with another. A valid-looking `catalog.json` may fail because a child link resolves incorrectly, an Item uses the wrong geometry or time fields, a Collection omits required extent information, or validation stops at the root and never checks descendants. This guide works from the outside in: inspect the files, validate the smallest object, verify links and assets, then validate the complete tree.
How EDK fits
For: GIS developers, remote-sensing engineers, data providers, geospatial platform operators, and analysts who need to publish a local or hosted STAC catalog and troubleshoot it before connecting it to a browser, search service, data lake, or downstream processing pipeline.
STAC is useful when the physical world is represented through observations that have both a place and a time: satellite scenes, aerial photographs, elevation products, point clouds, weather observations, environmental rasters, and other Earth-data assets. Its catalog structure turns those observations into discoverable geographic objects, while Item footprints, temporal fields, collection membership, and asset links provide the metadata needed for spatial and temporal computation. That makes STAC complementary to a world model such as E2. STAC can describe and organize source observations; a broader world model can relate those observations to persistent physical features such as roads, buildings, waterways, vegetation, infrastructure, and public assets. For example, a STAC workflow might identify imagery intersecting a region and time range, while a geographic computation workflow compares the imagery footprint with roads, construction permits, flood-prone areas, or other mapped features. The connection is genuine when catalog metadata is used to find, filter, compare, or compute about real places—not when STAC is treated as a generic document format.
- •Use STAC Item footprints and temporal intervals to find Earth-observation assets covering a particular city, watershed, road corridor, building cluster, or infrastructure project before performing geographic comparison or change analysis.
- •Combine catalog-level discovery with spatial computation: filter assets by bounding box or date, then relate the selected observations to physical features such as roads, waterways, vegetation, construction activity, public facilities, or utility infrastructure.
- •Use Collection summaries, asset roles, projection metadata, and links to make imagery or environmental datasets easier to discover alongside other geographic data sources that describe the same places.
The EDK outcome
Before you start
Basic familiarity with JSON, GeoJSON, file paths, HTTP URLs, and coordinate reference systems.
A small sample geospatial asset and its known footprint or bounding box.
Python 3 with a virtual environment.
PySTAC installed with validation support: `python -m pip install "pystac[validation]"`.
A decision about whether the catalog will be local, hosted as static files, or exposed through a search API.
Learning objectives
Distinguish the responsibilities of a STAC Catalog, Collection, Item, and Asset.
Diagnose failures in JSON parsing, STAC schema validation, link resolution, geometry, temporal metadata, and asset accessibility.
Validate a catalog from the smallest object through the complete linked tree.
Use a controlled smoke test to verify the catalog at its final hosting location.
Recognize the boundary between STAC metadata discovery and broader geographic computation.
Verification
Every JSON file parses successfully.
The root Catalog passes object-level validation.
At least one Collection and one Item pass validation independently.
Recursive validation completes without a failing child.
Relative and absolute links resolve from the final published location.
At least one representative Asset is reachable and returns the expected content type.
Item geometry, bounding box, temporal metadata, and projection information agree with the source data.
The catalog records enough provenance, licensing, and version information for another user to understand what the assets represent.
Troubleshooting
If `Catalog.from_file()` fails immediately, check JSON syntax, file encoding, and whether the file is actually JSON rather than an HTML error response.
If root validation passes but `validate_all()` fails, inspect the first child or Item link and validate that resource independently.
If a client reports a missing child, resolve the relative link from the directory containing the parent JSON file, not from the shell’s current working directory.
If the catalog appears in the wrong place on a map, check longitude-latitude order, the source CRS, geometry serialization, and whether the bounding box was transformed consistently.
If a Collection fails validation, inspect its extent, license, identifier, links, and summaries. Do not copy Item fields into the Collection without checking the Collection schema.
If an extension fails validation, confirm the extension URI, version, field names, and value types. Removing the declaration while leaving extension fields usually hides the underlying problem rather than fixing it.
If Assets return 403 or 404 responses, inspect object-storage permissions, URL encoding, signed URL expiry, bucket paths, and whether the published catalog points to development locations.
If thumbnails or previews load but the primary data does not, check Asset roles and links. A preview is not a substitute for the data Asset.
If validation becomes slow or memory-intensive, validate a representative sample first, partition the catalog, and consider an indexed or API-backed architecture for large collections.
If a downstream search system returns no results, confirm that it reads the Item geometry and temporal fields, recognizes the declared extensions, follows Collection links, and has indexed the current catalog version.
Next steps
Read the companion guide for creating the initial STAC Catalog, Collection, Item, and Asset objects.
Apply the production guide when the catalog needs stable hosting, versioned releases, automated validation, monitoring, or large-scale ingestion.
Add a STAC API only after the static resources, links, metadata, and asset accessibility are correct.
Relate cataloged observations to other geographic datasets when the workflow requires analysis of roads, buildings, waterways, infrastructure, environmental features, or change over time.
What a STAC catalog contains—and where failures usually occur
The core STAC model has three closely related object types. A Catalog provides links that organize and connect resources. A Collection extends the catalog concept with metadata describing a related group of Items, including spatial and temporal extent, licensing, keywords, and providers. An Item is the feature-level record: it uses GeoJSON-style geometry and properties to describe one or more spatiotemporal assets, with links to the actual files or services. (stacspec.org)
For troubleshooting, separate four concerns: JSON validity, STAC schema validity, link resolution, and data usability. A JSON parser can accept a document that does not conform to STAC. A schema validator can accept a document whose asset URL returns a 404. A catalog can be fully valid but still be difficult to search if Items lack meaningful footprints, timestamps, collection links, or consistent extension metadata.
- •Catalog: organizes linked STAC resources.
- •Collection: describes a related set of Items and adds collection-level metadata.
- •Item: describes a spatiotemporal feature and its Assets.
- •Asset: points to the actual downloadable file, service, thumbnail, metadata document, or other related resource.
Prerequisites and a controlled diagnostic setup
Use a small test catalog before debugging a large archive. Create one root Catalog, one Collection, and one Item that points to a known local or reachable asset. This makes it possible to distinguish a structural problem from a bad file, an inaccessible object store path, or a scale-related failure.
PySTAC is a practical Python library for reading, writing, creating, and validating STAC objects. Its validation support is optional, so install the validation extra explicitly. PySTAC can validate individual objects and recursively validate the contents of a Catalog or Collection. (pystac.readthedocs.io)
- •Python 3 and a virtual environment.
- •A small sample asset with a known location, such as a GeoTIFF or cloud object URL.
- •A text editor and a JSON parser.
- •PySTAC with validation support: `python -m pip install "pystac[validation]"`.
- •A reproducible directory or object-storage layout that will remain stable after publication.
Step 1: inspect the directory and parse every JSON file
Before changing STAC fields, confirm that the files you think exist actually exist. A common failure is generating correct JSON but moving `collection.json`, renaming an Item, or copying the catalog to another directory without preserving the relative paths used by links.
Start with a filesystem inventory and parse the JSON independently of STAC validation. This identifies syntax errors, duplicate or missing files, and accidental HTML error pages saved with a `.json` extension.
- •List the layout: `find catalog-root -type f | sort`.
- •Parse all JSON files: `find catalog-root -name '*.json' -print0 | xargs -0 -n1 python -m json.tool >/dev/null`.
- •Inspect the root object: `python -m json.tool catalog-root/catalog.json`.
- •Check that every referenced child file and every asset URL exists or is intentionally remote.
Step 2: validate the smallest object before the whole catalog
Validate the root Catalog, then the Collection, then one representative Item. This ordering prevents a large recursive error report from hiding the first structural defect. PySTAC exposes object-level validation and recursive validation; when validation fails, capture the object identifier and the field path in the exception rather than changing several fields at once. (pystac.readthedocs.io)
A minimal validation script can distinguish a parse problem from a schema problem:
- •`from pathlib import Path`
- •`import pystac`
- •`from pystac.validation import validate_all`
- •`root = pystac.Catalog.from_file(Path("catalog-root/catalog.json"))`
- •`root.validate()`
- •`root.validate_all()`
- •`print("catalog tree validated")`
- •`validate_all(root)` is useful when you want validation to operate recursively over the linked tree. If the root loads but recursion fails, inspect the failing child link and open that JSON file directly.
Step 3: diagnose links, paths, and asset accessibility
STAC catalogs are linked resources. A relative link such as `./collections/sentinel-2/collection.json` is resolved relative to the document containing it, not necessarily relative to the process working directory. Moving only the root file can therefore break an otherwise valid catalog.
Check the link `rel` values and targets. Catalogs commonly link to child resources with relations such as `child` and `root`; Items commonly link to their Collection and root. Asset entries should point to the data or service they describe and should include enough metadata for clients to understand the asset’s role and media type.
- •Check a local asset: `test -f catalog-root/assets/scene.tif && echo ok`.
- •Check an HTTP asset: `curl -I -L "https://example.invalid/scene.tif"`.
- •Check a JSON child link: `curl -fsSL "https://example.invalid/collection.json" | python -m json.tool >/dev/null`.
- •Look for links that use the wrong base directory, an outdated filename, an accidental Windows path, or a URL that is valid only inside a private network.
Step 4: verify Item geometry, time, and collection membership
An Item is meant to be spatially and temporally discoverable. Confirm that its `geometry` is valid GeoJSON, its `bbox` agrees with the geometry when present, and its temporal properties use the appropriate `datetime` or `start_datetime` and `end_datetime` pattern. Do not invent a timestamp when the source observation time is unknown; represent the uncertainty according to the applicable STAC specification and extension rules instead.
Coordinate order is another frequent source of apparently valid but geographically wrong catalogs. GeoJSON coordinates are expressed as longitude, latitude in geographic coordinate systems. If the source uses a projected coordinate reference system, make the projection metadata explicit through the appropriate STAC extension and ensure the geometry and metadata agree.
- •Confirm the geometry is not empty unless the data type and specification explicitly allow it.
- •Check longitude and latitude order with a known point.
- •Compare Item geometry and `bbox` numerically.
- •Confirm the temporal value uses UTC or an explicitly stated offset where applicable.
- •Confirm the Item links to the intended Collection and root Catalog.
Step 5: inspect Assets and extensions without overloading the core
STAC is intentionally extensible. The core specification does not define every domain-specific field; extensions add standardized fields for areas such as electro-optical imagery, projection information, scientific metadata, view geometry, raster data, and processing details. Declare each extension you use and follow that extension’s schema rather than adding similarly named custom fields with undocumented meanings. (stacspec.org)
Asset metadata should answer practical questions: What is this file? How should a client retrieve it? Is it the primary data, a thumbnail, metadata, a preview, or another related resource? What media type and roles apply? A catalog may pass core validation while remaining difficult to use if its Assets lack stable links, media types, roles, or domain-specific metadata.
- •Declare extension URIs in `stac_extensions` when required by the extension.
- •Use a correct media type such as `image/tiff`, `image/png`, or another type appropriate to the asset.
- •Use roles such as `data`, `thumbnail`, `overview`, or `metadata` only when they accurately describe the linked resource.
- •Keep custom fields namespaced or documented so they do not collide with future standard fields.
Step 6: run recursive validation and an operational smoke test
Once the root, Collection, representative Item, links, geometry, time fields, and Assets are correct, validate the full tree. For a large catalog, run validation in a controlled environment and record the first failing identifier, file path, and field. PySTAC’s recursive validation is designed to walk linked Catalogs, Collections, and Items; the STAC Validator project also provides command-line and Python validation tooling for STAC JSON and supports multiple STAC versions. (pystac.readthedocs.io)
Finish with an operational smoke test. Open the root document from its final hosting location, follow one Collection link, follow one Item link, and retrieve one representative Asset. This catches deployment problems that schema validation cannot detect, including permissions, incorrect content types, signed URLs that have expired, and object-storage paths that differ between development and production.
- •Validate the complete tree with `root.validate_all()`.
- •Open the final root URL with `curl -fsSL`.
- •Follow at least one root-to-Collection-to-Item path.
- •Retrieve one representative Asset and verify its response status and media type.
- •Record the catalog version, source-data version, generation time, and validation result for reproducibility.
Workflow
Create a minimal controlled test tree
Start with one root Catalog, one Collection, one Item, and one known Asset. Keep the file layout stable while diagnosing the catalog. A small tree makes it easier to determine whether the failure is structural, geographic, link-related, or operational.
catalog-root/
├── catalog.json
├── collections/
│ └── sample/collection.json
├── items/
│ └── sample-item.json
└── assets/
└── sample.tifParse JSON independently of STAC
Run a JSON parser over every catalog, collection, and item. If parsing fails, fix quotes, commas, encoding, or truncated files before investigating STAC fields.
find catalog-root -name '*.json' -print0 | xargs -0 -n1 python -m json.tool >/dev/nullLoad and validate the root object
Use PySTAC to load the root file and validate it. If this fails, do not begin with recursive validation; first fix the root object or its immediate links.
from pathlib import Path
import pystac
root = pystac.Catalog.from_file(Path('catalog-root/catalog.json'))
root.validate()
print('root catalog is valid')Validate the complete linked tree
After the root passes, recursively validate the Catalog, Collections, and Items. Capture the first failing identifier and file path. The failing child is often where an incorrect link, missing required field, invalid extension value, or malformed geometry appears.
root.validate_all()
print('catalog tree is valid')Check geographic and temporal semantics
Inspect one Item manually. Verify GeoJSON coordinate order, geometry, bounding box, datetime or interval fields, collection membership, projection metadata, and Asset links. A schema-valid object can still describe the wrong place or time if the source metadata was transformed incorrectly.
item = pystac.Item.from_file('catalog-root/items/sample-item.json')
print(item.id)
print(item.geometry)
print(item.bbox)
print(item.datetime)
print(item.get_collection())Test the published paths and assets
Repeat the traversal from the final hosting location. Open the root URL, follow one Collection link, follow one Item link, and retrieve one representative Asset. This verifies deployment behavior that local validation cannot prove.
curl -fsSL 'https://example.invalid/catalog.json' | python -m json.tool >/dev/null
curl -I -L 'https://example.invalid/assets/sample.tif'Questions teams ask
Why does my `catalog.json` parse successfully but fail as STAC?
A JSON parser checks only JSON syntax. STAC validation additionally checks the object type, required fields, field types, links, and any declared extensions. Load the file with PySTAC and call `root.validate()` to identify the schema-level problem, then validate descendants separately.
Should I create a Catalog or a Collection?
Use a Catalog when you primarily need a flexible hierarchy of linked resources. Use a Collection when a group of Items shares meaningful metadata such as spatial and temporal extents, license, providers, keywords, or summaries. A Collection is still linked from a Catalog, but it carries more information about the holdings.
Why does recursive validation fail even though the root Catalog is valid?
The root may contain valid JSON and valid root-level fields while linking to a malformed Collection or Item. It may also contain a relative link that resolves incorrectly from the root’s location. Open the failing child file directly, check its identifier and object type, and verify that every link is resolved relative to the document that contains it.
Can I use a projected coordinate system in a STAC Item?
You must make the coordinate reference system and geometry representation explicit according to the STAC core rules and any applicable projection extension. Do not silently mix projected coordinates with longitude-latitude GeoJSON assumptions. Check the projection extension documentation and validate both the geometry and projection metadata together.
Does a valid STAC catalog mean that a search service will work?
No. A static catalog can be schema-valid while still lacking reliable hosting, useful metadata, indexed search, pagination, authentication behavior, or service-level conformance. Test the final links and assets separately, and validate a STAC API if you are exposing the catalog through a search endpoint.
Keep exploring
create a stac catalog
The practical companion guide for building the initial Catalog, Collection, Item, and Asset structure before applying the troubleshooting workflow.
create a stac catalog production guide
The production-oriented companion for hosting, versioning, validating, and operating a STAC catalog after the basic structure works.
Sources
STAC Specification overview
Authoritative overview of Catalogs, Collections, Items, extensions, and the linked-resource model.
Open sourceSTAC official site
Official project description of the STAC ecosystem and its intended use for discovering spatiotemporal Earth assets.
Open sourcePySTAC concepts and validation documentation
Authoritative PySTAC guidance for object creation, validation, recursive validation, and the optional validation dependency.
Open sourcePySTAC validation API
Reference for validating STAC objects and serialized JSON, including recursive validation behavior.
Open sourceSTAC Validator repository
Official project repository for command-line and Python validation of STAC JSON against the specification.
Open source