Skip to main content

Troubleshooting

Common issues encountered during PeerTube-to-Vidra migration and how to resolve them.

Database Connection Issues

Cannot connect to PeerTube database

Symptom: API migration fails with failed to connect to source database

Causes and fixes:

  1. Firewall blocking PostgreSQL port:

    # Test connectivity from Vidra server
    nc -zv peertube-db-host 5432

    # If blocked, open the port or use an SSH tunnel
    ssh -L 5433:localhost:5432 user@peertube-server &
    # Then use localhost:5433 as source_db_host
  2. PostgreSQL not listening on external interfaces:

    # On PeerTube server, check postgresql.conf
    grep listen_addresses /etc/postgresql/*/main/postgresql.conf
    # Should be: listen_addresses = '*' (or specific IP)

    # Check pg_hba.conf allows remote connections
    grep -v '^#' /etc/postgresql/*/main/pg_hba.conf
    # Add: host peertube_prod peertube_readonly vidra-server-ip/32 md5
  3. Wrong credentials:

    # Test directly with psql
    PGPASSWORD=your-password psql -h peertube-db-host -U peertube -d peertube_prod -c "SELECT 1;"

Migration job stuck in "pending" or "validating"

Symptom: Job never transitions to "running"

Fix: Check Vidra logs for connection errors:

docker compose logs vidra | grep -i migration

Cancel the stuck job and retry:

curl -X DELETE http://your-vidra-host:8080/api/v1/admin/migrations/$JOB_ID \
-H "Authorization: Bearer $ADMIN_TOKEN"

Data Migration Issues

"A migration is already in progress"

Symptom: 409 Conflict when starting a new migration

Cause: An existing migration job is in a non-terminal state (pending, running, or validating).

Fix:

# List all jobs
curl http://your-vidra-host:8080/api/v1/admin/migrations \
-H "Authorization: Bearer $ADMIN_TOKEN" | jq '.data[] | {id, status}'

# Cancel the running job
curl -X DELETE http://your-vidra-host:8080/api/v1/admin/migrations/$RUNNING_JOB_ID \
-H "Authorization: Bearer $ADMIN_TOKEN"

Users imported with wrong roles

Symptom: Regular users have admin access, or admins are regular users

Cause: PeerTube uses numeric roles (0=admin, 1=moderator, 2=user) that need mapping.

Fix (manual migration):

-- Verify role mapping
SELECT username, role FROM users WHERE role = 'admin';

-- Fix if needed
UPDATE users SET role = 'user' WHERE username = 'some-user' AND role = 'admin';
UPDATE users SET role = 'admin' WHERE username = 'real-admin';

Missing channel-to-user relationships

Symptom: Channels appear but have no owner, or videos show wrong channel

Cause: Username matching failed during import (PeerTube account.name didn't match Vidra users.username).

Fix:

-- Find orphaned channels
SELECT c.handle, c.account_id
FROM channels c
WHERE c.account_id IS NULL OR c.account_id NOT IN (SELECT id FROM users);

-- Reassign to admin or correct user
UPDATE channels SET account_id = (SELECT id FROM users WHERE username = 'admin')
WHERE account_id IS NULL;

Comment threading broken

Symptom: Reply comments appear as top-level comments instead of nested

Cause: PeerTube uses integer IDs for comment parent references; manual migration scripts need a PeerTube-ID-to-Vidra-UUID mapping table.

Fix: Use a two-pass import with a mapping table:

-- Step 1: Create a persistent mapping table (not TEMP, since you need it across sessions)
CREATE TABLE IF NOT EXISTS comment_id_map (
peertube_id INT PRIMARY KEY,
vidra_id UUID NOT NULL
);

-- Step 2: During first-pass import (top-level comments), record the mapping
-- Add a RETURNING clause or insert into the map after each batch

-- Step 3: Import reply comments and resolve parent references
INSERT INTO comments (id, video_id, user_id, parent_id, body, status, created_at, updated_at)
SELECT
gen_random_uuid(),
v.id,
u.id,
parent_map.vidra_id, -- Resolved parent UUID from mapping table
sub.text,
'active',
sub."createdAt",
sub."updatedAt"
FROM dblink('dbname=peertube_staging', '
SELECT vc.id, vc.text, vc."createdAt", vc."updatedAt",
vc."inReplyToCommentId",
vid.name AS video_title,
a.name AS author_name
FROM "videoComment" vc
JOIN video vid ON vid.id = vc."videoId"
JOIN account a ON a.id = vc."accountId"
WHERE vc."inReplyToCommentId" IS NOT NULL
AND vc."deletedAt" IS NULL
') AS sub(
pt_id int, text text, "createdAt" timestamptz, "updatedAt" timestamptz,
in_reply_to int,
video_title text, author_name text
)
JOIN videos v ON v.title = sub.video_title
JOIN users u ON u.username = sub.author_name
JOIN comment_id_map parent_map ON parent_map.peertube_id = sub.in_reply_to;

-- Step 4: Clean up
DROP TABLE comment_id_map;

Duplicate username conflicts

Symptom: Import skips users with ON CONFLICT (username) DO NOTHING

Cause: PeerTube may have usernames that conflict with already-created Vidra users (e.g., "admin").

Fix: Review skipped users:

-- Find PeerTube users not in Vidra
SELECT a.name FROM dblink('dbname=peertube_staging',
'SELECT name FROM account') AS sub(name text)
WHERE NOT EXISTS (SELECT 1 FROM users WHERE username = sub.name);

Storage Issues

Videos not playing after migration

Symptom: Video page loads but player shows an error or buffering forever

Causes:

  1. Files not copied:

    # Check if the file exists
    ls -la /data/vidra/storage/web-videos/{video-uuid}.mp4
  2. Wrong file permissions:

    # Fix permissions (Vidra needs read access)
    chown -R 1000:1000 /data/vidra/storage/
    chmod -R 755 /data/vidra/storage/
  3. Static file handler not configured:

    # Verify Vidra serves static files
    curl -I http://localhost:8080/static/web-videos/{video-uuid}.mp4
    # Should return 200, not 404
  4. Database references don't match filenames:

    -- Check video file references in Vidra's DB
    SELECT v.id, v.title FROM videos v
    WHERE NOT EXISTS (
    -- Verify the referenced file exists on disk
    -- (Run this as a script, not pure SQL)
    );

HLS playback broken

Symptom: Adaptive streaming doesn't work; video only plays in one quality

Fix: Verify the HLS directory structure:

# Each video UUID should have a directory with master playlist
ls /data/vidra/storage/streaming-playlists/hls/{video-uuid}/
# Should contain: master.m3u8, {resolution}.m3u8, *.mp4 segments

# Validate master playlist
cat /data/vidra/storage/streaming-playlists/hls/{video-uuid}/master.m3u8
# Should list all quality variants

Thumbnails showing as broken images

Fix:

# Check thumbnail exists
ls /data/vidra/storage/thumbnails/{video-uuid}.jpg

# If using S3, verify the object exists
aws s3 ls s3://vidra-storage/thumbnails/{video-uuid}.jpg --endpoint-url $S3_ENDPOINT

Federation Issues

Other instances can't discover the migrated instance

Symptom: WebFinger returns errors or wrong data

Fix:

# Test WebFinger locally
curl "http://localhost:8080/.well-known/webfinger?resource=acct:admin@your-domain.com"

# Verify the domain matches your public URL
# Check .env: PUBLIC_URL=https://your-domain.com

ActivityPub followers lost

Expected behavior: ActivityPub followers from other instances need to re-follow after migration. The federation protocol will automatically rediscover your instance through WebFinger.

To speed up re-federation:

  1. Ensure WebFinger and NodeInfo endpoints work
  2. Contact administrators of major federated instances
  3. ActivityPub followers should automatically rediscover within 24-48 hours

Performance Issues

Migration running slowly

Symptom: API migration job has been running for hours with low entity counts

Possible fixes:

  1. Add indexes to PeerTube staging DB (for manual migration):

    CREATE INDEX IF NOT EXISTS idx_video_channel_id ON video("channelId");
    CREATE INDEX IF NOT EXISTS idx_comment_video_id ON "videoComment"("videoId");
  2. Increase PostgreSQL connection limits on both databases

  3. Run during off-peak hours to avoid resource contention

Vidra slow after large import

Fix: After importing large amounts of data, refresh database statistics:

-- Run ANALYZE on all imported tables
ANALYZE users;
ANALYZE channels;
ANALYZE videos;
ANALYZE comments;
ANALYZE playlists;
ANALYZE captions;

-- If needed, VACUUM to reclaim space
VACUUM ANALYZE;

Getting Help

If you encounter an issue not covered here:

  1. Check Vidra logs: docker compose logs vidra
  2. Check the migration job's error details via the API
  3. File an issue at github.com/yosefgamble/athena/issues with:
    • PeerTube version you're migrating from
    • Vidra version
    • Migration method used (API or manual)
    • Error messages and relevant logs
    • Instance size (approximate user/video counts)