Likely causes
- OG tags rendered by JavaScript: CardyB fetches raw HTML only. If your tags are injected client-side by React, Vue, or similar, CardyB never sees them.
- WAF or CDN blocking the crawler: Cloudflare Bot Fight Mode, AWS WAF, and similar services often block CardyB because it crawls from cloud infrastructure with rotating IPs.
- “Invalid URL: host IP” error: Bluesky rejects URLs that resolve to private or reserved IP addresses (localhost,
10.x.x.x,192.168.x.x) as a security measure. Domains with unusual DNS configurations can also hit this. - robots.txt blocking: if
BlueskyPreviewBotis disallowed, CardyB respects the restriction and returns nothing.
Diagnosis
curlyour URL and verify the OG tags are in the raw HTML, not injected after page load.- Simulate a CardyB request:
curl -A "Mozilla/5.0 (compatible; Bluesky Cardyb/1.1; +mailto:support@bsky.app)" https://yoursite.com/page- Check
https://yoursite.com/robots.txtand make sureBlueskyPreviewBotisn’t blocked. - Check your WAF/CDN logs for blocked requests from the CardyB user agent. Cloudflare users: Security > Events.
- Hit the CardyB API directly to see exactly what Bluesky gets:
curl "https://cardyb.bsky.app/v1/extract?url=https://yoursite.com/page"- Verify your domain resolves to a public IP, not a private or reserved range.
WAF and CDN blocking
CardyB runs on cloud infrastructure, so its requests look like bot traffic to protection systems. Add an allow rule for the user agent:
- Cloudflare: Security > WAF > Custom rules, skip bot checks for user agents containing
Bluesky Cardyb - AWS WAF: add a user-agent-based allow rule to your bot control rule group
Third-party AT Protocol apps
If you’re building a Bluesky client or bot, the AT Protocol API does not auto-generate cards from URLs. Your app must handle the full pipeline: fetch the URL, parse OG tags, download and compress the image under 1 MB, upload the blob, and construct the app.bsky.embed.external record.
Testing your fix
Hit the CardyB API after making changes:
curl "https://cardyb.bsky.app/v1/extract?url=https://yoursite.com/page"You should see JSON with your page’s title, description, and image URL. Then create a test post to confirm the card renders.