CLI Reference
Command-line interface
On first run, the tool prompts for configuration (database path and kernel storage directory). These are saved to ~/.config/spice-kernel-db/config.toml. All commands share a --db option to override the configured database path.
scan
Recursively scan a directory and register all kernel files.
spice-kernel-db scan <directory> [--mission NAME] [-v] [--archive]| Option | Description |
|---|---|
directory |
Root directory to scan recursively |
--mission |
Override auto-detected mission name |
-v, --verbose |
Print each registered file |
--archive |
Move files to the configured kernel directory and leave symlinks at the original locations |
# Auto-detect mission from path structure
spice-kernel-db scan /data/spice/JUICE/kernels
# Explicit mission label
spice-kernel-db scan /data/spice/generic_kernels --mission generic
# Verbose output
spice-kernel-db scan /data/spice/MRO/kernels -v
# Import kernels from a random directory into the central archive
spice-kernel-db scan /tmp/downloaded_kernels --mission JUICE --archiveWith --archive, each kernel file is moved into the configured kernel directory (organized as {kernel_dir}/{mission}/{type}/{filename}) and a symlink is left at the original location. This lets you import kernels from anywhere while keeping the original paths functional.
Symlinks require filesystem support. On Windows, Developer Mode or administrator privileges are needed. If symlink creation fails, the file is still moved and registered — only the symlink is skipped (with a warning).
stats
Print database summary statistics.
spice-kernel-db statsShows unique kernels, total locations, total size, number of duplicates, registered missions, and a breakdown by kernel type.
duplicates
Report all duplicated kernels.
spice-kernel-db duplicatesLists each kernel that exists in 2+ locations, showing all paths and missions, with a total wasted space calculation.
check
Check which kernels from a metakernel are available locally.
spice-kernel-db check [metakernel] [--mission NAME] [-v]| Option | Description |
|---|---|
metakernel |
Path to a .tm file or registry filename. Omit to select interactively from locally acquired metakernels. |
--mission |
Mission name for preferred-mission resolution |
-v, --verbose |
Show full per-file warnings instead of compact summary |
# Interactive — pick from local metakernels
spice-kernel-db check
# Explicit metakernel
spice-kernel-db check juice_crema_5_1.tm --mission JUICE
# Full per-file warnings
spice-kernel-db check juice_crema_5_1.tm -vReports found/missing counts, lists missing files, and shows warnings for cross-mission fallbacks. By default, warnings are grouped into a compact summary (dedup resolutions, cross-mission lookups). Use -v to see full per-file details.
If the metakernel was fetched from a remote server, check also queries the server to see if a newer version is available and prints a notice if so. This adds one HTTP request but does not download anything.
rewrite
Rewrite a metakernel with a local symlink tree.
spice-kernel-db rewrite <metakernel> -o <output> [--link-root DIR] [--mission NAME]| Option | Description |
|---|---|
metakernel |
Path to original .tm file |
-o, --output |
Output .tm path (required) |
--link-root |
Root for symlink tree (default: kernels/ next to output) |
--mission |
Mission name for preferred-mission resolution |
# Basic usage
spice-kernel-db rewrite juice_crema_5_1.tm -o juice_local.tm
# Custom symlink root
spice-kernel-db rewrite juice_crema_5_1.tm -o juice_local.tm \
--link-root /data/spice/unified
# Explicit mission
spice-kernel-db rewrite juice_crema_5_1.tm -o juice_local.tm --mission JUICEresolve
Find the local path for a single kernel filename.
spice-kernel-db resolve <filename> [--mission NAME]| Option | Description |
|---|---|
filename |
Kernel filename to look up |
--mission |
Preferred mission for resolution |
spice-kernel-db resolve naif0012.tls --mission JUICE
# /data/spice/JUICE/kernels/lsk/naif0012.tls
spice-kernel-db resolve mro_sc_2024.bc --mission JUICE
# /data/spice/MRO/kernels/ck/mro_sc_2024.bc
# ⚠ mro_sc_2024.bc: not found in [JUICE] registry, using copy from [MRO]Prints the resolved path to stdout and any warnings to stderr.
aliases
Show every filename a deduplicated kernel is known under. Content-addressed deduplication stores one physical file per unique content hash under a single canonical name; other filenames with identical content become aliases. This command lets you follow that trail from any name (or hash) back to the content and to all the sibling names it shares.
spice-kernel-db aliases [name-or-hash]| Option | Description |
|---|---|
name_or_hash |
A kernel filename (canonical or alias) or a SHA-256 (full or ≥6-char prefix). Omit to pick from the deduplicated kernels interactively. |
# Direct lookup
spice-kernel-db aliases bc_mpo_hga_scm_20220101_20230101_s20221229_v01.bc
# No argument → interactive picker over deduplicated kernels
spice-kernel-db aliasesPrints the content hash, canonical name, kernel type and size, the full list of alias filenames (with the canonical one marked), and every on-disk location. With no argument it lists every deduplicated kernel (those whose content is shared under more than one filename), sorted most-aliased first, and lets you pick one. Exits non-zero if a supplied name or hash is unknown.
The get, update, and list commands also annotate any deduplicated kernel inline with (+N aliases) in their kernel tables, pointing you at aliases <name> for the full trail.
Because identity is content-based, aliases surfaces names an archive (e.g. ESA) publishes the same bytes under — revealing, for example, that a _v13 kernel is byte-identical to _v12, or that two trajectory scenarios reuse the same solar-array/antenna kernels. This is a pure discovery feature: it needs no dedup step (symlinking duplicates is a separate, optional space-saving operation). See Discovering archive-side aliases.
verify
Deeply cross-check a metakernel against the database. Every entry in KERNELS_TO_LOAD is walked through PATH_VALUES/PATH_SYMBOLS substitution and validated.
spice-kernel-db verify [metakernel] [--deep] [--strict] [--json] [--mission NAME]| Option | Description |
|---|---|
metakernel |
Path to .tm file. Omit to select interactively from the registry. |
--deep |
Recompute SHA-256 of every entry’s target (slow). Default: size-only checks. |
--strict |
Exit non-zero on any non-OK finding. Default: only on fatal P0 issues. |
--json |
Emit structured JSON instead of a rich table. |
--mission |
Filter the interactive picker by mission. |
Per-entry status codes:
| Status | Severity | Meaning |
|---|---|---|
OK |
— | Verified |
DANGLING |
fatal | Symlink target missing |
NOT_FOUND |
fatal | No file at the resolved path |
NOT_FILE |
fatal | Path exists but isn’t a regular file |
TRAVERSAL |
fatal | Entry resolves outside every PATH_VALUE root |
HASH_MISMATCH |
fatal | (deep mode) target’s SHA-256 ≠ DB record |
SIZE_MISMATCH |
fatal | File size disagrees with DB record |
AMBIGUOUS |
fatal | Multiple non-superseded kernels rows for the same filename |
BAD_PATH_VALUE |
fatal | PATH_VALUES entry not absolute or directory missing |
UNREGISTERED |
warning | File exists but no kernels row — run scan |
# Quick check (size + presence)
spice-kernel-db verify ~/spice/juice/mk/juice_ops.tm
# Full hash recompute
spice-kernel-db verify ~/spice/juice/mk/juice_ops.tm --deep
# CI-friendly
spice-kernel-db verify juice_ops.tm --json --strictUse this after a get/update to confirm the rewritten metakernel is sound. --deep is the only mode that catches content corruption that preserves file size.
prune
Remove stale database or filesystem state. Three mutually exclusive modes:
# Mode 1 (default): locations whose file no longer exists on disk
spice-kernel-db prune [--execute]
# Mode 2: metakernel registry rows whose source URL returns 4xx
spice-kernel-db prune --metakernels [--execute] [--delete-files]
# Mode 3: dangling symlinks under each mission's download tree
spice-kernel-db prune --orphan-symlinks [--execute]| Option | Description |
|---|---|
--execute |
Actually remove entries. Default: dry run. |
--metakernels, --mk |
Metakernel-registry mode. Sends HEAD to each row’s effective URL (source_url if set, otherwise mission.mk_dir_url + filename); 403/404/410 = dead. |
--orphan-symlinks |
Walk each mission’s download tree (derived from metakernel_registry.mk_path) recursively and find symlinks whose target no longer exists. These accumulate when an underlying kernel store moves, or after Mode 1 removes a location row. |
--delete-files |
With --metakernels --execute: also unlink the on-disk .tm files. |
Network errors (timeouts, DNS failures) in --metakernels mode are never treated as dead — pruning would otherwise discard real state when you happened to be offline.
--metakernels and --orphan-symlinks are mutually exclusive — run them sequentially if you want both.
# Default — preview stale kernel locations
spice-kernel-db prune
# Find dead metakernel registry rows
spice-kernel-db prune --metakernels --execute
# Sweep up dangling symlinks left behind
spice-kernel-db prune --orphan-symlinks --executededup
Replace duplicate kernel files with symlinks.
spice-kernel-db dedup [--execute]| Option | Description |
|---|---|
--execute |
Actually replace files (default: dry run) |
# Preview (default, safe)
spice-kernel-db dedup
# Do it
spice-kernel-db dedup --executeThe canonical copy (the file that symlinks point to) is chosen with a preference for files in the generic mission.
metakernels (alias: mk)
List tracked metakernels or show detailed info about a specific one.
spice-kernel-db metakernels [name] [--mission NAME]
spice-kernel-db mk [name] [--mission NAME]| Option | Description |
|---|---|
name |
Optional: show info for a specific metakernel (by filename) |
--mission |
Filter listing by mission name |
# List all tracked metakernels
spice-kernel-db metakernels
# Filter by mission
spice-kernel-db metakernels --mission JUICE
# Detailed info for a specific metakernel
spice-kernel-db metakernels juice_crema_5_1.tmWhen no name is given, prints a summary table with kernel counts and availability. When a name is given, shows per-kernel status with type, size, and whether each kernel is in the database or missing.
get
Fetch a remote metakernel, show which kernels are needed, and download missing ones.
spice-kernel-db get [url] [--download-dir DIR] [--mission NAME] [-y] [--force]| Option | Description |
|---|---|
url |
URL to a remote .tm metakernel, or just a filename (e.g. juice_ops.tm). Omit to select interactively. |
--download-dir |
Override default kernel storage directory |
--mission |
Override auto-detected mission name (required if multiple missions known and using filename) |
-y, --yes |
Skip confirmation prompt |
--force |
Re-download all kernels even if already on disk (skips DB lookups and remote size queries) |
# By filename (after browsing a mission at least once)
spice-kernel-db get juice_ops.tm
# By filename with explicit mission (when multiple missions are known)
spice-kernel-db get juice_ops.tm --mission JUICE
# By full URL
spice-kernel-db get https://naif.jpl.nasa.gov/pub/naif/JUICE/kernels/mk/juice_ops.tm
# Auto-confirm download
spice-kernel-db get juice_ops.tm -yWhen a filename is given instead of a URL, the tool looks up the mk/ directory URL from the missions table (configured via mission add). Mission names support case-insensitive prefix matching (e.g. --mission bepi matches BEPICOLOMBO). If multiple missions are known, use --mission to disambiguate.
The tool fetches the remote metakernel, resolves each kernel entry to a full URL, checks your local database, queries remote file sizes (in parallel), and displays a summary table. Downloaded kernels are stored preserving the remote subdirectory structure (e.g. lsk/, spk/, ck/) and automatically registered in the database.
Archived metakernels. ESA (and some NAIF directories) rotate older versioned metakernels into a former_versions/ subdirectory once a newer version supersedes them. When a filename you request is not present in the live mk/ listing, get automatically retries under former_versions/<filename> before failing. The kernels referenced by the older metakernel are typically still available at their original locations (ESA in particular is purely additive — old kernel files are kept alongside new ones), so the rest of the download proceeds unchanged:
# A 2022-era versioned metakernel — auto-fetched from former_versions/
spice-kernel-db get juice_crema_2_0_ops_v200.tm --mission JUICEIf both the live and former_versions/ URLs 404, the error names both attempted URLs so you can diagnose archive layouts that don’t follow this convention.
update
Re-fetch a metakernel from its source URL and download any new or missing kernels.
spice-kernel-db update [metakernel] [--mission NAME] [--download-dir DIR] [-y] [--force]| Option | Description |
|---|---|
metakernel |
Metakernel filename or path. Omit to select interactively. |
--mission |
Override mission name |
--download-dir |
Override default kernel storage directory |
-y, --yes |
Skip confirmation prompt |
--force |
Re-download all kernels even if already on disk |
# Interactive selection
spice-kernel-db update
# By filename
spice-kernel-db update juice_ops.tm
# Auto-confirm
spice-kernel-db update juice_ops.tm -yThis is a convenience command that combines looking up the source URL from the metakernel registry and calling get. It’s the recommended action after check or browse reports that a remote update is available. Metakernels added via scan (without a source URL) cannot be updated this way — use get with an explicit URL instead.
browse
Browse remote metakernels in a NAIF mission mk/ directory, or list known directories.
spice-kernel-db browse [url] [--mission NAME]| Option | Description |
|---|---|
url |
URL to a mission’s mk/ directory, or a mission name (omit to list known directories) |
--mission |
Override auto-detected mission name |
--show-versioned |
Show versioned snapshots under each metakernel |
--sort {name,date} |
Row ordering. name (default) is alphabetical. date sorts by the Latest remote modification date ascending, so the most recently updated metakernels appear at the bottom — handy for spotting fresh updates at a glance. |
--archived |
Browse the mission’s former_versions/ subdirectory instead of the live mk/ listing. Each archived metakernel is rendered on its own row (no base-name aggregation) because archived snapshots are distinct historical files, not byte-identical copies of a current file. |
--filter SUBSTRING |
Case-insensitive substring filter on metakernel filenames. Particularly useful when combined with --archived to narrow listings of a thousand-plus entries. |
# List all known mk/ directories (from missions table and previously acquired metakernels)
spice-kernel-db browse
# Browse by mission name (prefix matching, case-insensitive)
spice-kernel-db browse JUICE
spice-kernel-db browse bepi # matches BEPICOLOMBO
# Browse by full URL
spice-kernel-db browse https://naif.jpl.nasa.gov/pub/naif/JUICE/kernels/mk/
# Sort by latest remote modification date (newest at the bottom)
spice-kernel-db browse JUICE --sort date
# Browse only the archived versions in former_versions/
spice-kernel-db browse JUICE --archived
spice-kernel-db browse JUICE --archived --sort date # combine with sort
# Narrow a large listing with a substring filter (combinable with --archived)
spice-kernel-db browse JUICE --archived --filter crema_5_1Without a URL, lists configured missions from the missions table:
Configured missions
Mission mk/ URL
─────── ──────────────────────────────────────────────────────────
JUICE https://spiftp.esac.esa.int/data/SPICE/JUICE/kernels/mk/
MRO https://naif.jpl.nasa.gov/pub/naif/MRO/kernels/mk/
Use 'spice-kernel-db browse <mission>' to scan a specific directory.
Use 'spice-kernel-db mission add' to add another mission.
With a URL, fetches the Apache directory listing, parses .tm file entries, groups them by base name (stripping version tags like _v461_20251127_001), and displays a compact summary:
Remote metakernels: JUICE (https://naif.jpl.nasa.gov/.../mk/)
Metakernel Versions Latest Local
───────────────────────────────── ──────── ──────────────── ────────
juice_crema_5_0.tm 1 2025-08-15 11:00 no
juice_ops.tm 3 2025-11-27 09:30 yes
juice_plan.tm 2 2026-02-02 14:00 outdated
Total: 3 unique | 6 files | 1 locally acquired
Run 'spice-kernel-db get <name>' to update outdated metakernels.
Use --show-versioned to see individual snapshots.
The Local column shows three states:
- yes — locally acquired and up to date (or scan-acquired, where remote date is unknown)
- outdated — locally acquired but the remote copy has been modified since acquisition
- no — not acquired locally
With --show-versioned, versioned snapshots are listed under each base metakernel:
juice_ops.tm 2025-11-27 09:30 12K yes
snapshot: juice_ops_v230_20221128_001.tm 2022-11-28 10:00 8K
snapshot: juice_ops_v461_20251127_001.tm 2025-11-27 09:30 12K
coverage
Check SPK body coverage in a metakernel. See the Coverage page for full details.
spice-kernel-db coverage <body> [metakernel] [--mission NAME]| Option | Description |
|---|---|
body |
NAIF body ID (e.g. 399) or body name (e.g. Earth) |
metakernel |
Path to a .tm file or registry filename. Omit to select interactively. |
--mission |
Mission name for preferred-mission resolution |
# Interactive — pick metakernel, resolve body name
spice-kernel-db coverage Earth
# Explicit
spice-kernel-db coverage 399 juice_ops.tm --mission JUICERequires the optional spiceypy dependency: pip install spice-kernel-db[spice]
mission
Configure missions for filename-based acquisition and browsing. Mission names are matched case-insensitively and support prefix matching — e.g. bepi matches BEPICOLOMBO, ju matches JUICE (as long as the prefix is unambiguous).
mission add
Set up a new mission. Runs interactively with no arguments; non-interactive when a name (or --mk-dir-url) is given.
Interactive flow:
- Choose a server:
[1] NASA [2] ESA - View available missions from that server (split into “with metakernels” and “no default mk/”)
- Select one by number; or type the name of a “no default mk/” mission to consult the curated registry
- Configure deduplication:
Enable deduplication for this mission? [Y/n]: - Store in database
spice-kernel-db mission add| Option | Description |
|---|---|
name (positional, optional) |
Mission name. When given, prompts are skipped. |
--server-url <URL> |
Archive server base URL. Required with positional name unless the mission name is unambiguous on a known server. |
--mk-dir-url <URL> |
Override the metakernel directory URL (bypasses auto-discovery). Validated with a HEAD request. |
--no-dedup |
Disable deduplication for this mission. |
--use-planetarypy |
Delegate kernel management to planetarypy if the [planetarypy] extra is installed and the mission is registry-flagged. |
# Interactive
spice-kernel-db mission add
# Non-interactive, explicit metakernel directory
spice-kernel-db mission add LRO \
--server-url https://naif.jpl.nasa.gov/pub/naif/ \
--mk-dir-url https://naif.jpl.nasa.gov/pub/naif/LRO/data/spice/mk/
# Non-interactive, let the tool auto-discover (curated registry + alt-path probe)
spice-kernel-db mission add OSIRIS-REX --server-url https://naif.jpl.nasa.gov/pub/naif/When discovery finds multiple candidate metakernel directories, the command lists them and asks you to re-run with --mk-dir-url. When it finds none, it points at the troubleshooting docs.
Curated metakernel registry
For missions whose metakernels live outside the default {server}/{MISSION}/kernels/mk/ path — typically on PDS nodes rather than NAIF — the package ships mission_registry.toml, a curated list of verified alternate locations. The mission add flow checks this registry first, then falls back to the standard kernels/mk/ probe.
An empirical NAIF survey found that no missions use the speculative patterns (spice_kernels/mk/, data/spice/mk/, etc.) one might expect from naming convention alone; the registry is therefore deliberately sparse and only grows through verified contributions. See docs/troubleshooting.qmd for the contribution format. Registry entries may use absolute URLs (PDS nodes, mission websites), not just {server}/{m} placeholders.
After setup, the command prints next steps for acquiring metakernels.
mission list
Show all configured missions with their server, deduplication status, and mk/ directory URL.
spice-kernel-db mission listExample output:
Configured missions:
Mission Server Dedup mk/ URL
─────── ────── ───── ──────────────────────────────
JUICE ESA yes https://spiftp.esac.esa.int/data/SPICE/JUICE/kernels/mk/
MRO NASA no https://naif.jpl.nasa.gov/pub/naif/MRO/kernels/mk/
mission remove
Remove a configured mission from the database.
spice-kernel-db mission remove <name>| Option | Description |
|---|---|
name |
Mission name to remove |
spice-kernel-db mission remove MROconfig
Show or update configuration.
spice-kernel-db config [--setup]| Option | Description |
|---|---|
--setup |
Re-run the interactive first-time setup |
# Show current settings
spice-kernel-db config
# Re-run setup (change database path, kernel directory, etc.)
spice-kernel-db config --setupWithout --setup, prints the current configuration: database path, kernel directory, and config file location.
reset
Delete the database and start fresh.
spice-kernel-db reset [-y]| Option | Description |
|---|---|
-y, --yes |
Skip confirmation prompt |
# Interactive (asks for confirmation)
spice-kernel-db reset
# Skip confirmation
spice-kernel-db reset -yDeletes only the DuckDB database file. Kernel files in the configured kernel directory are not touched. After resetting, you can re-index existing kernels:
spice-kernel-db scan ~/.local/share/spice-kernel-db/kernels