Migration Troubleshooting
This guide covers common issues encountered during migration and how to resolve them.
Connection Issues
Provider Returns "Connection Refused"
Symptom: The /v1/migration/connect endpoint returns a connection error or timeout.
Root causes:
- The
base_urlis incorrect or unreachable from your FeatureSignals instance - Network security groups or firewalls are blocking outbound traffic
- A self-hosted instance is behind a VPN or private network
Solutions:
- Verify the
base_urlfor your provider:- LaunchDarkly:
https://app.launchdarkly.com - Unleash SaaS:
https://app.unleash-hosted.com(varies by region) - Unleash Self-hosted: Your custom domain (e.g.,
https://unleash.internal.example.com) - Flagsmith SaaS:
https://api.flagsmith.com - Flagsmith Self-hosted: Your custom domain
- LaunchDarkly:
- Test connectivity from your FeatureSignals server:
curl -I https://app.launchdarkly.com/api/v2/flags
- For self-hosted providers, ensure DNS resolution works and the API is accessible from the FeatureSignals network
- If using Kubernetes, check NetworkPolicy and egress rules
Authentication Fails (HTTP 401)
Symptom: The API returns HTTP 401 Unauthorized when connecting.
Root causes:
- API key is expired, revoked, or incorrectly copied
- Insufficient permissions (missing required scopes)
- Key type mismatch (e.g., client-side key used instead of admin key)
Solutions:
- Generate a fresh API key from the source provider
- Verify the key has the correct scope:
- LaunchDarkly: Needs
*:adminor read access to flags and environments - Unleash: Needs Admin token type (not client-side)
- Flagsmith: Needs Server-Side SDK key (not client-side key)
- LaunchDarkly: Needs
- Check for leading/trailing whitespace or line-break issues in the key
- For Flagsmith, ensure the key is the
Server-Side SDK Key, not theEnvironment API Key
Rate Limit Errors (HTTP 429)
Symptom: The migration returns "rate limit exceeded" or HTTP 429 responses.
Root causes:
- The migration is making too many requests too quickly
- Your source provider plan has a low rate limit
- Concurrent migrations are running against the same source
Solutions:
- The migration adapter includes built-in rate limiting with exponential backoff — wait for retries to succeed
- Reduce the number of concurrent migration requests
- Check your source provider's rate limit policy:
- LaunchDarkly: 300 requests/min for paid plans
- Unleash: 200 requests/min for paid plans
- Flagsmith: Varies by plan
- If retries are exhausted, restart the migration after the rate limit window resets
Flag Import Issues
Some Flags Are Skipped During Import
Symptom: The migration report shows fewer flags imported than expected.
Root causes:
- Flags are archived or deleted in the source system
- Flags have incomplete or invalid configuration
- Flags use unsupported data types or operators
- Duplicate flag keys already exist in the target project
Solutions:
- Review the migration error log for specific skip reasons:
"errors": [{ "flag": "legacy-feature", "error": "skipped — flag is nil" },{ "flag": "broken-flag", "error": "skipped — no targeting rules" }]
- Ensure archived flags are unarchived before migration
- Check for flags with missing variations or configurations
- If duplicate keys exist, either:
- Remove the conflicting flags from the target project before re-running
- Use a key prefix or suffix in your migration script to avoid collisions
- Flags using unsupported operators are converted to the closest equivalent — review these after migration
Default Values Are Incorrect
Symptom: Imported flags show null or unexpected default values.
Root causes:
- Flags without explicit default values in the source system
- Variation indexing mismatch during the mapping process
- Flagsmith config flags without initial values
Solutions:
- After migration, review and update default values in the FeatureSignals dashboard
- For LaunchDarkly:
- Boolean flags without explicit variations default to
[true, false] - The default value is taken from the first environment's fallthrough
- If no environments exist, the first variation's value is used
- Boolean flags without explicit variations default to
- For Flagsmith:
- Config-type flags without initial values default to
null - Update
initial_valuein Flagsmith before migration, or fix after
- Config-type flags without initial values default to
- Use the flag bulk-edit feature in FeatureSignals to update multiple defaults at once
Targeting Rules Are Incorrect
Symptom: Flags are imported but targeting rules don't evaluate as expected.
Root causes:
- Operator mapping differs between systems
- Context attribute names don't match (e.g.,
uservsuserId) - Match type (
ALLvsANY) is incorrect for complex rules - Prerequisite chains are flattened and may not work as expected
Solutions:
- Review the operator mapping reference for your provider:
- Verify context attribute names match what your application sends:
// If the rule expects "userId" but your app sends "user_id"const value = client.boolVariation('my-flag', {key: 'user-123',attributes: { userId: 'user-123' } // Changed from user_id}, false);
- For rules with multiple conditions, verify the match type (
allvsany):all: Every condition must match (AND logic)any: At least one condition must match (OR logic)
- Test evaluation with known inputs to verify rule behavior
Segment Import Issues
Segments Are Not Imported
Symptom: The migration completes but segments are missing.
Root causes:
- The provider's segment endpoint requires a project ID that wasn't provided
- Segment API is unavailable or requires different authentication
- The provider importer doesn't support segment import (LaunchDarkly)
Solutions:
- LaunchDarkly: The LaunchDarkly importer maps
segmentMatchclauses toSegmentKeysin targeting rules, but does not import segment definitions. You must re-create segments manually in FeatureSignals. - Unleash: Ensure your Unleash instance has the segments API enabled. Self-hosted instances may have the feature disabled.
- Flagsmith: Ensure the SDK key has access to the project. The importer discovers the project ID from the environment details endpoint.
Segment Conditions Are Flattened
Symptom: Nested segment conditions appear as a flat list.
Root causes:
- The source system (Flagsmith) supports deeply nested segment rules with
ANY/ALLlogic - The current import adapter flattens nested rules into a single condition list
- Nested AND/OR logic may not be preserved exactly
Solutions:
- Review imported segments after migration for nested rule complexity
- If you have segments like this Flagsmith configuration:
The flattened result may not preserve the correct groupingRule: (country = "US" AND age > 18) OR (country = "CA" AND age > 21)
- Manually re-create complex nested segments in FeatureSignals
- Use the FeatureSignals dashboard to adjust condition groupings
Environment Issues
Environment Names Are Incorrect
Symptom: Imported environments don't match the source system.
Root causes:
- The provider uses different naming conventions for environments
- Unleash environments are named at the instance level, not project level
- Flagsmith may only discover the current environment if project-level access is unavailable
Solutions:
- For Unleash: Environments are fetched from the
/api/admin/environmentsendpoint. Unleash does not associate environments with specific projects, so all instance-level environments are imported. - For Flagsmith: If only one environment is imported, the SDK key may not have project-level access. Use an SDK key with broader access or migrate environments one at a time.
- Environment colors/descriptions are not migrated. Update these in the FeatureSignals dashboard after migration.
Missing Environment States
Symptom: Flags only have a single "default" environment state instead of per-environment configurations.
Root causes:
- Unleash stores strategies at the toggle level, not per environment
- The import maps all strategies to a single
defaultenvironment state - Multi-environment flags from other providers may not have been fetched correctly
Solutions:
- This is expected for Unleash — strategies are defined once and evaluated across all environments
- After migration, you can create per-environment configurations in FeatureSignals by duplicating the state and adjusting as needed
- For LaunchDarkly, ensure the
expand=environmentsquery parameter is included in the API request (the importer does this automatically) - For Flagsmith, ensure the SDK key has access to all environments
Performance Issues
Migration Is Too Slow
Symptom: Large migrations (1000+ flags) take too long to complete.
Root causes:
- Each flag is fetched and mapped individually
- The built-in rate limiter deliberately throttles requests to avoid overwhelming the source
- Identity overrides for Flagsmith require additional API calls
Solutions:
- Use the
/v1/migration/estimateendpoint to get a time estimate before starting - For large migrations (5000+ flags), consider:
- Breaking the migration into batches by tag or prefix
- Migrating during off-peak hours
- Migrating environments separately
- Check the migration logs for slow API responses from the source provider
- Consider using the direct API integration scripts for batch operations (see IaC Export)
Migration Reports Out of Memory
Symptom: The migration fails with an out-of-memory error in the FeatureSignals server logs.
Root causes:
- Extremely large flag configurations (many variations, rules, or conditions)
- Very large numbers of identity overrides (100,000+)
- Insufficient server resources allocated to FeatureSignals
Solutions:
- Increase server memory allocation for the FeatureSignals API container
- Migrate in smaller batches by filtering by tags or environment
- For identity overrides, use the dedicated identity migration endpoint instead of the full migration
- Consider exporting flags via IaC methods for bulk operations
Post-Migration Issues
Evaluation Results Differ
Symptom: The same flag evaluates to different values in FeatureSignals vs the source provider.
Root causes:
- Operator semantics differ between systems
- Evaluation context attributes use different names or casing
- Percentage rollouts are calculated differently
- Match type (
ALLvsANY) differs for multi-condition rules - Prerequisite flags were not imported or have different keys
Solutions:
- Test with identical inputs: Ensure the evaluation context is exactly the same (same attribute names, same keys)
- Check percentage rollouts:
- LaunchDarkly uses a 0–100,000 weight scale
- FeatureSignals uses basis points (0–10,000)
- The conversion should be exact:
FS = LD / 10
- Verify prerequisite flags: Ensure all prerequisite flags exist in FeatureSignals with their original keys
- Check segment references: Segments referenced by key in rules must exist in FeatureSignals
- Run a side-by-side comparison:
// Evaluate in both systems and compareconst ldValue = ldClient.boolVariation('my-flag', user, false);const fsValue = fsClient.boolVariation('my-flag', context, false);console.log(`LD: ${ldValue}, FS: ${fsValue}, Match: ${ldValue === fsValue}`);
Flags Missing from Dashboard
Symptom: Imported flags don't appear in the FeatureSignals dashboard.
Root causes:
- The target project ID in the migration request was incorrect
- The import completed but flags were created in a different project
- UI or caching issue — try refreshing the page
Solutions:
- Verify the target project ID:
curl -X GET https://api.featuresignals.com/v1/projects \-H "Authorization: Bearer YOUR_JWT"
- Check the migration status to confirm completion
- Clear your browser cache or open the dashboard in an incognito window
- Query the API directly to confirm flags exist:
curl -X GET https://api.featuresignals.com/v1/projects/proj_abc123/flags \-H "Authorization: Bearer YOUR_JWT"
General Troubleshooting
Check Server Logs
If migration issues persist, check the FeatureSignals server logs:
# Docker Compose
docker compose logs api | grep migration
# Kubernetes
kubectl logs -l app=featuresignals-api | grep migration
Look for:
WARNlevel messages about skipped flags or segmentsERRORlevel messages about API failures- Rate limit warnings with specific provider names
Enable Debug Logging
For detailed migration debugging, set the log level to debug:
# Set environment variable
LOG_LEVEL=debug docker compose up -d
Then re-run the migration and examine the detailed logs.
Still Having Issues?
If the troubleshooting steps above don't resolve your issue:
-
Collect diagnostic information:
- Migration status response
- Server logs around the time of the migration
- Source provider API response (test with curl)
- FeatureSignals configuration (Docker version, deployment mode)
-
Contact Support:
- Community Edition: Open a GitHub issue with the collected information
- Enterprise Edition: Contact your support representative or email support@featuresignals.com
Common Error Codes
| Error Code | Meaning | Resolution |
|---|---|---|
CONNECTION_REFUSED | Cannot reach the source provider API | Verify base URL and network connectivity |
AUTH_FAILED | API key rejected (HTTP 401) | Generate a new key with correct scope |
RATE_LIMITED | Too many requests (HTTP 429) | Wait and retry, or reduce concurrency |
NOT_FOUND | Project or resource doesn't exist | Verify project_key and resource identifiers |
SKIPPED_NIL_FLAG | Null flag encountered | Archive/delete null flags in source |
SKIPPED_STALE | Archived or stale flag | Unarchive in source if needed |
DUPLICATE_KEY | Flag key already exists | Remove conflicting flag or use different target |
UNSUPPORTED_OPERATOR | Operator can't be mapped | Review and adjust mapping manually |
INVALID_RULE | Rule has no conditions or clauses | Review and fix source rule configuration |
Next Steps
- Migration Overview — understand the full workflow
- Migrate from LaunchDarkly — step-by-step guide
- Migrate from Unleash — step-by-step guide
- Migrate from Flagsmith — step-by-step guide
- Infrastructure as Code Export — IaC patterns