Start Free
← All posts

October 2, 2026

Configuring Nighthawk recording uploads: prerequisites and failure handling

If you run self-hosted streaming and want finished recordings to land in object storage, Nighthawk can automatically upload them as they complete. This guide focuses on the real prerequisites, how to configure the uploader, what can fail (and how it fails), and a checklist to verify your setup end-to-end.

See /server-docs for broader installation and configuration context.

What the recording uploader does (and when it runs)

Nighthawk triggers recording uploads when a recording/DVR segment completes. The local control plane handles an internal on_dvr event and, when upload is configured, dispatches the file to your object store. The implementation only proceeds for real recording files under the server’s recordings directory and validates simple, safe filenames before touching the filesystem. Treat hook bodies as untrusted; the server defends by scoping what it accepts for upload.

Important: if recording/DVR features are not present in your license, the runtime disables the DVR/recording block at startup. In that case, no recording files are produced and there is nothing to upload.

Prerequisites and decisions

Before you start, align on these requirements and choices:

  • Recording/DVR enabled for your deployment. If DVR/recording features are not licensed, the runtime will turn this block off at startup and uploads will never be triggered.
  • Object storage target and credentials ready. You need a bucket name plus access and secret keys. Region defaults to us-east-1 if you don’t set one explicitly.
  • Upload retention policy. Decide whether to keep local recordings after a successful upload or delete them automatically. By default, local files are retained; deletion occurs only when you explicitly enable it.
  • Optional: S3-compatible endpoints (Cloudflare R2, MinIO, DigitalOcean Spaces, etc.). The server package notes describe support for S3-compatible storage by setting an endpoint variable in addition to credentials and bucket.

Step-by-step configuration

1) Enable recording/DVR

  • Ensure your deployment includes recording/DVR features. If they are not present, the runtime will disable the block and you will not get on-dvr events or recording files to upload. See /server-docs for the Recording & Features section within the Server Docs page.

2) Set required environment variables

  • NH_S3_BUCKET: your target bucket name.
  • NH_S3_ACCESS_KEY and NH_S3_SECRET_KEY: credentials for object storage.
  • Optional: NH_S3_REGION (default is us-east-1 if omitted).
  • Optional: NH_S3_DELETE_LOCAL (set to 1/true/on/yes to delete the local file after a successful upload).
  • Optional (S3-compatible stores): per the server package notes, set the endpoint variable alongside the bucket and credentials to target non-AWS S3-compatible providers.

3) Restart the container

  • On startup, Nighthawk validates your upload configuration. If you set a bucket but did not provide access/secret keys, it logs an error and disables S3 uploads for that run. Fix the environment and restart.

4) Generate a recording and let it finish

  • Publish a test stream, let the server record, and then stop the stream so the recording finalizes. This emits the internal on_dvr event, which the local control plane uses to kick off the upload routine.

5) Verify in storage (and locally)

  • Check your object store for the uploaded recording. Object keys mirror the local layout (e.g., app/stream/2026-09-03_12-00-00.flv, optionally with a prefix if you configured one per server package notes).
  • If you enabled NH_S3_DELETE_LOCAL and the upload succeeded, the local file should be removed. If the upload failed after retries or deletion is not enabled, the local file remains on disk.

Failure modes and what to expect

Understanding concrete failure behavior helps you design safe operations and monitoring.

  • Missing credentials at startup
  • Behavior: If NH_S3_BUCKET is set without both NH_S3_ACCESS_KEY and NH_S3_SECRET_KEY, the server logs an error and disables S3 uploads for that session. No upload attempts will be made until you provide the keys and restart.
  • Path validation and hook safety
  • Behavior: The on_dvr handling validates a safe filename pattern and only accepts files that live under the recordings directory. This reduces risk from malformed or adversarial hook bodies but does not replace broader system hardening.
  • Network or object store errors during upload
  • Behavior: Each recording upload is a signed PUT. The uploader retries up to three times when errors occur. Retries improve robustness but do not guarantee success.
  • After all retries fail
  • Behavior: The uploader gives up and keeps the local file. You can reprocess or re-upload it later using your own tooling.
  • Post-success deletion
  • Behavior: Local deletion happens only after a successful upload and only when NH_S3_DELETE_LOCAL is explicitly enabled. If not enabled, local files are retained even on success.
  • Webhook notifications about stream lifecycle (if you forward them)
  • Behavior: If you also forward lifecycle events to your backend via the event webhook setting, delivery is fire-and-forget with a short timeout. Design your handler to be fast and resilient; events may be lost if your endpoint is slow or unavailable.

Verification checklist

Use this short list to confirm end-to-end behavior in a staging or test environment.

  • At startup
  • Recording/DVR features are not disabled in logs.
  • No error complaining about a set bucket with missing access/secret keys.
  • During a test stream
  • Recording files appear in the local recordings directory.
  • When the stream stops and recording finalizes
  • The uploader attempts a signed PUT; transient failures are retried up to three times.
  • On success, the object appears in your bucket under the expected key layout. If NH_S3_DELETE_LOCAL is enabled, the local file is removed; otherwise, it remains.
  • On failure after three attempts, the local file stays in place.
  • If webhooks are in use
  • Your endpoint receives expected JSON posts promptly, and your handler returns a quick 2xx.

Troubleshooting tips

  • “Uploads disabled” at startup
  • Confirm NH_S3_BUCKET, NH_S3_ACCESS_KEY, and NH_S3_SECRET_KEY are all set. Any missing key will disable uploads for that run.
  • Nothing to upload
  • Ensure recording/DVR is enabled in your license and not disabled at startup.
  • Wrong region
  • If your bucket is not in us-east-1, set NH_S3_REGION explicitly.
  • Non-AWS S3-compatible storage
  • Follow the server package notes for setting the endpoint variable with your provider’s S3-compatible endpoint.
  • Operational visibility
  • Monitor for repeated upload attempts and “giving up” messages. Because failed uploads retain local files, include disk space alerts for the recordings volume to avoid surprises.

For related configuration context and the recordings feature overview, start at /server-docs.

Own your streaming infrastructure

Nighthawk Server: perpetual license from $995 — pay once, own forever. Or start free on Nighthawk Cloud.

Get Started →