To be released.
Released on May 25, 2026.
- Fixed a bug where the media proxy returned
404 Not Foundfor remote media whose upstream server labeled the payload asapplication/octet-streamorbinary/octet-streameven though the bytes were valid image, video, or audio data. The proxy now sniffs magic bytes to recover the real MIME type in these cases. [#498]
Released on May 21, 2026.
- Upgraded Fedify to 2.2.3 to fix a security vulnerability in Linked Data Signature verification that could allow certain signed activities to be interpreted differently than intended. [CVE-2026-42462]
Released on May 20, 2026.
-
Upgraded Drizzle ORM to 1.0.0-rc.2 and migrated Hollo's relational query definitions to the new relations API. This has no intended user-facing behavior changes, but the first migration after upgrading may need one extra database permission check. Drizzle 1 upgrades its own migration log table,
drizzle.__drizzle_migrations, by addingnameandapplied_atcolumns. PostgreSQL only allows thatALTER TABLEwhen the migration is run by the table owner.If
pnpm run migratefails withmust be owner of table __drizzle_migrations, first check which role owns Drizzle's migration log table:SELECT n.nspname AS schema, c.relname AS table_name, pg_get_userbyid(c.relowner) AS owner FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE n.nspname = 'drizzle' AND c.relname = '__drizzle_migrations';
If the owner is not the same role Hollo uses in
DATABASE_URL, run the following SQL as the current table owner or a database admin, replacinghollowith your Hollo database user:ALTER SCHEMA drizzle OWNER TO hollo; ALTER TABLE drizzle.__drizzle_migrations OWNER TO hollo; ALTER SEQUENCE IF EXISTS drizzle.__drizzle_migrations_id_seq OWNER TO hollo;
Then run
pnpm run migrateagain with Hollo's normalDATABASE_URL. If your database provider does not allow ownership transfers, run this one migration once with the database role that already ownsdrizzle.__drizzle_migrations. -
Cancel running PostgreSQL queries when the corresponding
GETorHEADrequest is aborted, such as when a client disconnects or quickly switches away from a timeline column. Hollo now tracks the underlying postgres.js query handles used by Drizzle and calls PostgreSQL cancellation for in-flight queries tied to the aborted read-only request. This reduces wasted database work and helps keep the connection pool available under repeated client-side aborts. The existingstatement_timeoutrecommendation remains useful as a backstop for queries that cannot be tied to a safe HTTP request. -
Added passkey (WebAuthn) authentication. The admin Auth page now has a “Passkeys” section for enrolling and managing passkeys, and the public login page presents a “Sign in with passkey” button (with the email/password form tucked behind a toggle) whenever at least one passkey is enrolled. Both device-bound and synced (multi-device) passkeys are accepted. A passkey on its own counts as multi-factor authentication, so a successful passkey sign-in is accepted in place of the TOTP step — the user is not asked for a one-time code in the same session.
Hollo uses the @simplewebauthn/server library for verification and ships the matching browser helper as a static asset linked only from the auth and login pages. Registration uses
residentKey: requiredanduserVerification: required, so every enrolled passkey is discoverable and tied to a biometric or PIN gesture. Registration challenges are bound to the current login session with a server-enforced 5-minute TTL, and login challenges are stored in a single-usepasskey_login_challengestable so a captured cookie + assertion pair can be redeemed at most once. [#487] -
Added optional split-domain WebFinger support. When the new
HANDLE_HOSTandWEB_ORIGINenvironment variables are set, Hollo uses Fedify'soriginconfiguration so that fediverse handles (e.g.@alice@example.com) and ActivityPub actor URIs (e.g.https://ap.example.com/@alice) can live on different domains. The Mastodon-compatible/api/v1/instanceand/api/v2/instanceendpoints exposeHANDLE_HOSTas the instance domain when this is configured, so clients display the correct@user@HANDLE_HOSThandle. Both variables must be set together; setting only one is a startup error. They must be configured before the first account is created — changing the handle domain after federation has begun breaks remote follow relationships; on startup Hollo logs a warning when the configuredHANDLE_HOSTdoes not match the existing account's stored handle. Operators must also configure their reverse proxy on the handle domain to redirect/.well-known/webfingertoWEB_ORIGIN. See the Split-domain WebFinger guide. [#161, #484] -
Added a media proxy that re-serves remote avatars, headers, post attachments, custom emojis, and preview-card images from Hollo's own origin. This sidesteps CORS configurations on remote object stores and prevents the visitor's browser from talking directly to the source server. Controlled by a new
MEDIA_PROXYenvironment variable with three levels: [#481, #483, #493]off(default): the Mastodon API and web UI hand the original remote URL to clients, matching the historical behaviour.proxy: every remote media URL is rewritten to a signed/proxy/<sig>/<b64url>path served by Hollo itself. The proxy runs SSRF checks on the upstream URL and on every redirect target, allows only image/video/audio Content-Types (image/svg+xml is explicitly blocked to avoid same-origin XSS), caps the body at 32 MiB, and serves the response withCache-Control: public, max-age=2592000, immutableandX-Content-Type-Options: nosniff. No on-disk cache.cache: same URL rewriting, but the streamed body is persisted to the configured storage backend asproxy/<sha256>.bin, with a content-type sidecar alongside it atproxy/<sha256>.json. Subsequent requests skip the upstream fetch. Remote actor avatars for accounts with an approved follow relationship to the local account are also prefetched into this same cache when the actor is stored or refreshed, so stale upstream avatar files can keep rendering after Hollo has seen them once. The admin dashboard at /thumbnail_cleanup can purge the cache on demand.
MEDIA_PROXYalso accepts the Boolean synonymstrue/on/1(as aliases forproxy) andfalse/off/0(as aliases foroff). Disk caching is opt-in only via the explicitcachevalue.Outbound federation is unaffected: Hollo still publishes the original remote URLs in ActivityPub
icon,image,attachment, and emojiTagreferences. -
Added a
REMOTE_MEDIA_THUMBNAILSenvironment variable that controls whether Hollo downloads incoming remote attachments to generate a local WebP thumbnail. Set tooffto skip the upstream fetch and Sharp pipeline entirely, storing the remote URL itself as the thumbnail URL—useful in combination withMEDIA_PROXY=proxyorcacheto free up the disk space the local thumbnails would otherwise occupy. Defaults toon(the historical behavior). [#481, #483] -
Added FEP-044f quote authorization and policy support on top of the Mastodon-compatible quote APIs. [#457, #459, #460]
- Added persistent quote states for
pending,accepted,rejected,revoked, andunauthorizedquotes, plus quote target and authorization IRIs for federation. - Hollo now enforces quote policy, quote target visibility, block
relationships, follower-only quote permissions, and direct-message
mention requirements when creating a quote through
POST /api/v1/statuses. Remote public posts without an advertised FEP-044f quote policy are treated as legacy quote targets and can be quoted without waiting for quote authorization. - Implemented
quote_approval_policyhandling on status creation and editing, and addedPUT /api/v1/statuses/:id/interaction_policyfor updating a status' quote policy after publication. quotes_countnow includes only accepted quotes and is updated when quotes are accepted, rejected, revoked, created, deleted, or received through federation.GET /api/v1/statuses/:id/quotesnow lists only accepted quotes, and quote revocation keeps quote target metadata while removing the quote from accepted quote lists and counts.- Published outbound FEP-044f
quote,quoteAuthorization, andinteractionPolicy.canQuoteproperties on ActivityPub objects, while keeping the legacyquoteUrlproperty for compatibility. - Parsed inbound FEP-044f
quotetargets and quote approval policies from remote objects, including support for the legacyquoteUrlproperty. - Added federation handling for
QuoteRequest,Accept(QuoteRequest),Reject(QuoteRequest), andDelete(QuoteAuthorization), allowing Hollo to request quote authorization from remote servers, accept or reject incoming quote requests, and revoke quotes when a remote quote authorization is deleted. - Added dereferenceable local
QuoteAuthorizationActivityPub objects for accepted quotes.
- Added persistent quote states for
-
Added custom field editing to the admin account creation and editing forms, allowing up to 10 label–value pairs per profile (beyond Mastodon's limit of 4). Field values support Markdown and mention syntax. The Mastodon-compatible
PATCH /api/v1/accounts/ update_credentialsendpoint now also accepts up to 10 custom fields viafields_attributes[0]throughfields_attributes[9]. -
Added
LOG_FILE_FORMATenvironment variable to control the format of the log file set byLOG_FILE. Valid values arejsonl(the default, JSON Lines format) andlogfmt(logfmt format). -
Fixed preview card generation for remote posts whose content only links to mentioned accounts. Hollo now excludes ActivityPub
Mentiontargets from remote preview-card link detection even when the source server, such as NodeBB, emits plain profile links in the post HTML instead of links marked with amentionclass. -
Fixed a bug in
PATCH /api/v1/accounts/update_credentialswhere submitting any credential update (e.g.display_name) withoutfields_attributeswould silently wipe all existing custom profile fields from the public profile, API responses, and federation output. -
Added an ActivityPub
quote-inlinefallback to thecontentof explicit quote posts created through the Mastodon API. Software that does not support quote posts can now still show the quoted post permalink, while quote-aware software can hide the fallback paragraph by class name. -
Hid incoming
quote-inlinefallback paragraphs from Mastodon API status content and profile pages when Hollo can render the structured quoted post. If the quoted post is unavailable, the fallback link remains visible so the quoted URL is not lost. -
Posts on the public profile and hashtag pages now render Open Graph link previews—a thumbnail (when
og:imageis set), the host name, the page title, and a short description—for each post that has a storedpreview_card. Posts with attached media or shown as quoted posts hide the preview to avoid visual clutter. [#458] -
Refreshed the entire server-rendered front-end. Hollo replaces Pico CSS with a new design system documented in DESIGN.md and styled through UnoCSS (Wind4, Icons, Typography, and Web Fonts presets). [#458]
- The design language is achromatic by default; each account owner's
theme color tints the profile, post, hashtag, and owner-specific
dashboard pages through
--theme-50through--theme-950CSS variables injected on<html>. - Web Fonts are loaded from bunny.net: Inter for Latin, Noto Sans KR/JP/SC for CJK, and JetBrains Mono for code. Lucide icons replace ad-hoc iconography.
- Every public and dashboard page was rebuilt: login, setup, OTP, the public home, account profiles, single post permalinks, the hashtag stream, the account list and editor, custom emojis, federation, thumbnail cleanup, the OAuth consent screen, and the dashboard auth (2FA) panel.
- Posts render their bodies as
prosemarkdown with brand-colored links, attached media as a two-column grid, polls as brand-tinted bars, quoted posts as an inset card, and link previews as a media-object card. The single-post permalink page additionally enlarges the focal post. - Forms share a small set of primitives (
Field,TextField,TextareaField,SelectField,CheckboxField,FieldSection, andSubmitButton) that the auth, account, emoji, federation, thumbnail cleanup, and migrate forms all use. The theme color picker on the account form is a 20-swatch grid; the username field is bracketed by@and@hostchips so the resulting fediverse handle is obvious. - Dark mode follows
prefers-color-scheme: darkautomatically, with primary buttons stepping frombrand-600tobrand-700so they don't dominate dark surfaces. Text selection adopts the active brand color. - Hollo's logos are self-hosted from
/public/instead of being fetched from jsDelivr. The 22 Pico-generated *.min.css files are removed; UnoCSS emits a single src/public/uno.css whose URL is cache-busted by file mtime.
- The design language is achromatic by default; each account owner's
theme color tints the profile, post, hashtag, and owner-specific
dashboard pages through
-
Added public Followers and Following pages on profile screens, with pagination (100 entries per page) and a substring search filter over display name and handle. The followers list is always public. The following list is gated by a new per-account setting, Make following list public (off by default); when off, the page returns 404 Not Found, the corresponding ActivityPub
followingcollection is hidden from federation, and the Mastodon-compatibleGET /api/v1/accounts/:id/followingendpoint returns an empty array. The toggle also round-trips throughPATCH update_credentialsashide_collections. [#491] -
Added public reaction list pages anchored to each local post:
/@:handle/:id/likeslists the accounts that liked the post,/@:handle/:id/shareslists the accounts that boosted it,/@:handle/:id/reactions/:emojilists the accounts that reacted with a specific emoji, and/@:handle/:id/quoteslists the posts that quote it. Each page features the original post above the list. On the profile feed and post permalink page, the per-post like, share, quote, and reaction-emoji indicators now link into these pages for local posts; remote posts continue to display the counts as plain text. [#490] -
Added avatar and header image upload to the admin account creation and editing forms, with drag-and-drop support and in-page image preview. Files are stored using the same storage backend as the Mastodon-compatible API (
PATCH /api/v1/accounts/update_credentials). -
Search queries on account handles, names, and post content now use PostgreSQL trigram indexes via the pg_trgm extension, improving
ILIKEsearch performance. Thepg_trgmextension is enabled automatically when the migration is applied. -
Fixed a performance bug on the account edit page where saving an account always triggered a network lookup of @hollo@hollo.social regardless of whether the “Receive Hollo news” setting had actually changed. The lookup now only happens when the news-following state genuinely changes.
-
Improved the performance of authenticated API requests by replacing the complex multi-table JOIN query in the
tokenRequiredmiddleware with a lightweight single-table lookup. Account owner data is now fetched on demand only by routes that actually need it, and requests that fail scope validation no longer touch the accounts table at all. [#127, #467] -
Fixed a bug where incoming ActivityPub posts with timestamps more than 12 hours in the future were accepted and stuck to the top of the federated timeline, enabling timeline manipulation via forged timestamps. Such posts are now silently ignored. [#67, #466]
-
Fixed a crash when persisting ActivityPub posts with a
publisheddate before the Unix epoch (January 1, 1970), which causeduuidv7()to receive a negative timestamp. [#67, #466] -
Fixed
min_idhandling onGET /api/v1/timelines/public,GET /api/v1/timelines/home,GET /api/v1/timelines/list/:list_id, andGET /api/v1/timelines/tag/:hashtagto follow Mastodon's pagination semantics:min_idnow returns the posts immediately newer than the cursor (rather than the most recent posts above it), so gap-loading clients such as SubwayTooter can converge on arbitrarily large gaps.since_idis now honoured on these endpoints as well, andmin_idtakes precedence when both are supplied. Timeline responses also include arel="prev"entry in theLinkheader alongside the existingrel="next"entry, and keeprel="next"even when a bounded gap page returns fewer statuses than the requestedlimit, so clients no longer have to guess which cursor parameter to use or stop walking partial gaps. [#479, #482, #492] -
Optimized Mastodon-compatible timeline loading after the Drizzle ORM upgrade. Home, list, public, and hashtag timelines now use a smaller relation graph that avoids fetching columns and nested relations that are not needed for timeline status serialization. They also fetch matching post IDs first, then hydrate only those posts with the timeline status projection, so empty cursor checks and heavily filtered timelines avoid running the relation-heavy query at all. The ID selection and hydration run in the same read-only repeatable-read snapshot, preserving timeline eligibility consistency while reducing the size and cost of the SQL generated for large timelines, especially list timelines on instances with many stored posts, without changing the API response format. Timeline
limitquery parameters are now capped at 1000 to keep these queries bounded even when clients request unusually large pages. -
Fixed a performance bug that caused profile page queries to take hundreds of seconds on a cold PostgreSQL buffer cache and trigger a thundering herd that exhausted the connection pool. Two root causes: [#489]
posts.actor_idhad no composite index withpublished, so timeline queries thatORDER BY published DESCperformed a full sort of all matching rows. A B-tree index on(actor_id, published)is now created by migration.- Every API response that fetches a list of posts used a lateral
join to eagerly load all direct replies for each post, even
though only the denormalized
replies_countcounter is actually used in the Mastodon API serialization. The lateral join is removed from all list-context queries (getPostRelations, timelines, notifications, outbox, etc.). The ActivityPub object serializer now also usesreplies_countfor therepliescollectiontotalItemsinstead of reloading every reply. Single-post views (the public post permalink page) still fetch replies but are now capped at 20 per request.
-
Fixed a performance bug where the NodeInfo endpoint performed a sequential scan of the entire
poststable on every request becauseposts.updatedhad no index. On large instances (e.g. 4 M rows / 13 GB) this took 15–20 seconds per query; since NodeInfo is polled frequently (Caddy health checks, remote servers), the slow queries piled up and could exhaust the connection pool. A B-tree index onposts.updatedis now created by migration. [#488] -
Further optimized the NodeInfo endpoint with three changes that together reduce a previously 42-second query to a handful of milliseconds:
- Rewrote the
activeMonthandactiveHalfyearqueries from aRIGHT JOIN+countDistinct(full scan of all posts) to anEXISTSsemi-join that performs at most one index lookup per local account owner. - Added a composite B-tree index on
(actor_id, updated)to support theEXISTSsubquery without heap fetches. - Added a 5-minute in-process TTL cache on the NodeInfo dispatcher so repeated polls by external directories and health checkers no longer hit the database at all.
- Rewrote the
-
Optimized the
GET /api/v2/instanceendpoint. Thelanguagesfield was previously computed by a full scan of thepoststable on every request. A new partial composite indexposts_actor_id_language_indexon(actor_id, language) WHERE language IS NOT NULLturns this into an Index-Only Scan, and a 5-minute in-process response cache absorbs repeated calls so the database is queried at most once per 5 minutes. -
Improved hashtag timeline and featured tag performance by adding a GIN index on
posts.tags. All?and?|operator lookups on the tags column (hashtag timeline, featured tag counts, profile hashtag filters, and tag pages) previously caused a full sequential scan of the 4 M+ rowpoststable, taking several seconds even on a warm cache. The new index cuts these to index lookups. -
The
TIMELINE_INBOXESfeature flag, introduced in Hollo 0.4.0, now defaults totrue. Set it tofalseexplicitly to opt out. The flag will be removed entirely in Hollo 1.0.0, when timeline inbox mode will be the only supported behavior. -
Upgraded Fedify to 2.2.2.
-
Added Traditional Chinese (繁體中文;
zh-TW) documentation.
Released on May 21, 2026.
- Upgraded Fedify to 2.1.14 to fix a security vulnerability in Linked Data Signature verification that could allow certain signed activities to be interpreted differently than intended. [CVE-2026-42462]
Released on May 19, 2026.
-
Fixed a security vulnerability where any federated actor could send a
Deleteactivity to remove cached remote posts authored by any other actor, because the inbox handler matched only on the post IRI without verifying the deleter's identity.Deleteactivities are now ignored unless the actor's origin matches the post author's origin. -
Fixed a security vulnerability where an
Updateactivity could overwrite or first-materialize a remote post under another instance's authority. The inbox handler now refuses anUpdatewhose actor origin does not match the embedded object'sidorigin. -
Fixed a security vulnerability where an
Announceactivity from a different origin than the announced object could first-materialize a cached post from attacker-controlled embedded content, masquerading as another actor's post. Cross-origin announces of previously unknown objects are now re-fetched from the canonical URL before being persisted, and the embedded body is no longer trusted to overwrite a post that is already known locally.As a deliberate trade-off, a cross-origin
Announceof a previously unknown post is dropped when the canonical origin is unreachable (down, rate-limiting, or rejecting Hollo's signed fetch). Honoring the embedded body in that case would re-introduce the masquerade vector that this change closes—an attacker can always craft an embedded object whoseidandattributedToagree on a victim origin, so the only safe source for the canonical content is the canonical origin itself. In practice this affects relay-mediated boosts and cross-instance reposts when the source instance is temporarily offline; locally cached posts and same-origin announces are unaffected. -
The login and OTP session cookies are now set with
HttpOnly,SameSite=Lax, and (over HTTPS)Secure. Previously these cookies were set without explicit attributes, so a single reflected XSS could exfiltrate the session and cross-site POSTs could forge admin actions. -
Hono's CSRF middleware is now applied to every cookie-authenticated web route (
/login,/login/otp,/logout,/setup,/auth,/accounts,/emojis,/federation) and toPOST /oauth/authorize. Without this, a malicious page could submit a hidden cross-site form to trigger state-changing actions (disable 2FA, delete an account, silently authorize an OAuth app, etc.) on behalf of a logged-in admin./oauth/token,/oauth/revoke,/oauth/userinfo, and the/api/*namespace continue to authenticate with client credentials or bearer tokens and are intentionally not affected. -
The application error handler now returns the response carried by
HTTPExceptioninstead of rethrowing it as a generic 500. Without this, middleware that signals refusal by throwingHTTPException(403, …)(the new CSRF middleware, among others) would have surfaced as opaque 500 responses to clients. -
Incoming
Follow,Like,EmojiReact, andAnnounceactivities from a blocked actor are now silently dropped. Previously a block only flipped auto-approval on incoming follow requests and did nothing for protected accounts, likes, reactions, or announcements—a blocker still saw notifications and timeline entries from the actor they had blocked. -
Pinned the transitive
fast-xml-parserdependency (carried in via the AWS SDK that backs S3 storage) usingpnpm.overrides. v4 consumers now resolve to^4.5.5(fixing the critical entity- encoding bypass and several high-severity parser issues) and v5 consumers resolve to^5.7.0. Each AWS SDK is kept on its expected major version to preserve API compatibility; the single remaining “XMLBuilder unescaped delimiter” moderate advisory is only patched on v5.7.0+ and is not addressed here because forcing AWS SDK v4 consumers onto fast-xml-parser v5 would risk runtime regressions on S3 deployments. -
Hollo now warns at startup whenever
LOG_QUERY=trueis set. The flag causes drizzle-orm to emit every SQL query together with its bound parameter values, which include OAuth access tokens (stored plain in the database), authorization codes, and other secrets; leaving it enabled in production exposes those secrets to anyone with read access to the application logs (or to a downstream collector such as Sentry or a file sink). -
The OAuth PKCE code-challenge check and the OAuth multi-credential client-secret consistency check are now compared in constant time using
crypto.timingSafeEqual. (The primary client-secret authentication path runs as a Postgres equality predicate and is unchanged.) The PKCE comparison is between two SHA-256 hashes (low practical timing-attack risk) and the multi-credential consistency check only fires when a client presents the same credentials via more than one mechanism, so neither was a confirmed exploitation primitive, but constant-time comparison is the correct defence-in-depth posture for any user-space operation on a secret.
Released on May 14, 2026.
-
Fixed a bug where boosting a quote post would incorrectly copy the
quote_idto the outer boost wrapper status, causing clients like SubwayTooter to fail to display the quoted post correctly. Thequote_idandquotefields now only appear inside the innerreblogobject. [#480] -
Fixed a bug where no logs were output when running as a worker node (
NODE_TYPE=worker). The logging system was only initialized when the web server started, so worker-only processes ran silently regardless of theLOG_LEVELsetting. [#478]
Released on May 10, 2026.
- Upgraded Fedify to 2.1.12 to fix a critical SSRF (Server-Side Request Forgery) vulnerability where private IPv4 addresses encoded as IPv6 literals could bypass security checks during remote ActivityPub object fetching.
Released on May 5, 2026.
- Fixed a security vulnerability where the hashtag follow/unfollow API endpoints were missing an ownership filter, allowing a single authenticated request to modify followed tags for all account owners in the database. [#429 by tomaioo]
Released on April 27, 2026.
- Fixed thumbnail cleanup preview counts over 999 being truncated after the localized count was passed through the redirect URL. The preview now keeps the raw count in the URL and formats it only when rendering. [#451]
Released on April 27, 2026.
-
Added support for separating worker nodes from the web server for better scalability in high-traffic scenarios. This allows running web server and background workers (Fedify message queue and import worker) in separate processes, preventing heavy federation workloads from slowing down web server responsiveness. This is particularly beneficial for instances with thousands of followers where a single post can generate thousands of outbox messages. [#350]
- Added
NODE_TYPEenvironment variable to control which components run in each process:all(default, current behavior),web(web server only), orworker(workers only). - All nodes share the same PostgreSQL database, which acts as the message
queue backend using
LISTEN/NOTIFYfor real-time message delivery. - Added comprehensive documentation for Docker Compose, systemd, and manual deployment setups with worker separation.
- Added
pnpm workerscript for running worker-only nodes.
- Added
-
Reduced idle memory usage by lazy-loading several heavy dependencies and startup-only code paths based on actual memory measurements. This lowers the baseline footprint of
NODE_TYPE=all,web, andworkerdeployments, especially on single-user instances with filesystem storage. [#435]- Markdown formatting now loads Shiki only when rich text formatting is actually needed, instead of at server startup.
- Filesystem deployments no longer pull S3-specific storage code into the initial web server startup path.
- The web server and worker process now import each other's code paths
only when the selected
NODE_TYPEneeds them. - Preview card scraping, media processing, and authentication helpers now load on demand instead of eagerly during route registration.
-
Added a production build step powered by
tsdown, and changedpnpm prodandpnpm workerto run the compiled JavaScript output with Node.js instead of running TypeScript throughtsx. Docker images now build these JavaScript files in a builder stage and include them in the runtime image. [#357] -
Moved remote replies scraping from synchronous post ingestion to a rate-limited background worker. Remote posts now enqueue reply collection scraping jobs instead of fetching nested replies inline, which prevents slow or very large remote reply collections from delaying federation processing. [#445, #447]
- Added per-origin throttling and
429 Too Many Requestsbackoff for remote replies scraping. - Added bounded scraping controls:
REMOTE_REPLIES_SCRAPE_DEPTH,REMOTE_REPLIES_SCRAPE_MAX_ITEMS,REMOTE_REPLIES_SCRAPE_INTERVAL_SECONDS,REMOTE_REPLIES_SCRAPE_BACKOFF_SECONDS, andREMOTE_REPLIES_SCRAPE_COOLDOWN_SECONDS.
- Added per-origin throttling and
-
Added automatic refresh of stale remote actor profiles. When receiving activities like
AnnounceorCreate(Note), Hollo now checks if the actor's cached data is stale and asynchronously refreshes their profile in the background. This helps keep remote actor information (avatars, display names, etc.) up to date without relying solely onUpdateactivities from remote servers. [#348]- Added
REMOTE_ACTOR_STALENESS_DAYSenvironment variable to configure how many days before a remote actor's data is considered stale. Defaults to7days. - Added
REFRESH_ACTORS_ON_INTERACTIONenvironment variable. When set totrue, checks for stale actors on all activity types (likes, emoji reactions, follows, etc.). Whenfalse(default), only checks on activities that appear in timelines (Announce,Create).
- Added
-
Added Mastodon 4.5-compatible quote post APIs. The
quotefield on Status entities now uses the MastodonQuoteentity format ({ state, quoted_status }) instead of the previous Fedibird-style flat status format. Thequote_idfield is kept for backward compatibility.- Added
quoted_status_idparameter toPOST /api/v1/statusesas the Mastodon 4.5 way to create quote posts (alongside existingquote_id). - Added
quotes_countfield to Status entities. - Added
quote_approvalfield to Status entities indicating whether a post can be quoted. - Added
GET /api/v1/statuses/:id/quotesendpoint to list quotes of a post with cursor-based pagination. - Added
POST /api/v1/statuses/:id/quotes/:quoting_status_id/revokeendpoint to let users revoke quotes of their posts. - The
quote_approval_policyparameter is accepted but ignored (all public/unlisted posts are freely quotable).
- Added
-
Added automatic cleanup of unreachable remote actors on permanent delivery failures. When sending activities to followers' inboxes fails permanently, Hollo now cleans up the associated records to avoid retrying delivery to dead servers.
- On
404 Not Found: removes follower relationships for the failed actor so that future activities are no longer delivered to them. The account record itself is preserved. - On
410 Gone: deletes the remote account entirely (along with associated follows, mentions, likes, etc. via cascade) since the actor is explicitly marked as permanently gone.
- On
-
Improved inbox handling for deleted remote actors using Fedify 2.1.0's unverified activity hooks. Hollo now acknowledges unverifiable
Deleteactivities with202 Acceptedwhen the signing key fetch fails with410 Gone, preventing repeated delivery retries for actors that have already been permanently deleted. -
Optimized follower-only status visibility checks by preloading approved follow relationships and reusing simple
WHERE INconditions for status, conversation context, quote, and timeline queries. [#173, #448] -
Added
FEDIFY_DEBUGenvironment variable to enable the Fedify debugger, an embedded real-time dashboard for inspecting ActivityPub traces and activities. When enabled, the debug dashboard is accessible at/__debug__/. Intended for development use only. -
Added outbound activity ordering keys for stateful federation actions, using Fedify 2.0's ordered message delivery support. This ensures remote servers process related actions in order, including post create/update/delete, reblog/unreblog, like/unlike, emoji reaction/unreaction, follow request lifecycle messages, block/unblock, and post updates triggered by replies and poll votes.
-
Fixed remote account force refresh and actor refresh getting stuck when a canonical fediverse handle had moved to a new actor IRI while a stale remote account row still claimed the old handle. Hollo now verifies the canonical handle owner via WebFinger, deletes the stale remote account and its dependent data, and then updates or inserts the current actor. When the conflict cannot be verified safely, force refresh now shows an explicit canonical handle conflict error instead of failing with a raw database unique-constraint error. [#424]
-
Added profile-specific tagged post pages at
/:handle/tagged/:tag, so users can browse only posts from a given profile that use a particular hashtag. The Mastodon-compatibleGET /api/v1/accounts/:id/statusesendpoint now also applies its existingtaggedquery parameter to filter account timelines by hashtag. [#420] -
Added an account-level preference for whether content warnings should be expanded by default. The setting is available in the dashboard account editor and is now returned from
GET /api/v1/preferences, which helps clients like Phanpy honor each account's preferred CW behavior. [#425] -
Fixed Mastodon API compatibility for clients such as the official Mastodon iOS app by returning empty arrays for unimplemented trends and suggestions endpoints instead of
404 Not Foundresponses. The suggestions endpoints still require an authenticated user token. [#421, #427 by Vignesh] -
Added a new dashboard page for thumbnail cleanup at
/thumbnail_cleanup. Thumbnails from remote posts that have not been bookmarked, liked, reacted to, shared nor quoted by a local account before a given cut-off data can be mass-deleted in order to lower storage demand. The original posts are not deleted, neither is the relationship to the original media nor thealttext. [#409, #436 by aliceif] -
Upgraded Fedify to 2.1.10.
Released on May 21, 2026.
- Upgraded Fedify to 1.10.10 to fix a security vulnerability in Linked Data Signature verification that could allow certain signed activities to be interpreted differently than intended. [CVE-2026-42462]
Released on May 19, 2026.
-
Fixed a security vulnerability where any federated actor could send a
Deleteactivity to remove cached remote posts authored by any other actor, because the inbox handler matched only on the post IRI without verifying the deleter's identity.Deleteactivities are now ignored unless the actor's origin matches the post author's origin. -
Fixed a security vulnerability where an
Updateactivity could overwrite or first-materialize a remote post under another instance's authority. The inbox handler now refuses anUpdatewhose actor origin does not match the embedded object'sidorigin. -
Fixed a security vulnerability where an
Announceactivity from a different origin than the announced object could first-materialize a cached post from attacker-controlled embedded content, masquerading as another actor's post. Cross-origin announces of previously unknown objects are now re-fetched from the canonical URL before being persisted, and the embedded body is no longer trusted to overwrite a post that is already known locally.As a deliberate trade-off, a cross-origin
Announceof a previously unknown post is dropped when the canonical origin is unreachable (down, rate-limiting, or rejecting Hollo's signed fetch). Honoring the embedded body in that case would re-introduce the masquerade vector that this change closes—an attacker can always craft an embedded object whoseidandattributedToagree on a victim origin, so the only safe source for the canonical content is the canonical origin itself. In practice this affects relay-mediated boosts and cross-instance reposts when the source instance is temporarily offline; locally cached posts and same-origin announces are unaffected. -
The login and OTP session cookies are now set with
HttpOnly,SameSite=Lax, and (over HTTPS)Secure. Previously these cookies were set without explicit attributes, so a single reflected XSS could exfiltrate the session and cross-site POSTs could forge admin actions. -
Hono's CSRF middleware is now applied to every cookie-authenticated web route (
/login,/login/otp,/logout,/setup,/auth,/accounts,/emojis,/federation) and toPOST /oauth/authorize. Without this, a malicious page could submit a hidden cross-site form to trigger state-changing actions (disable 2FA, delete an account, silently authorize an OAuth app, etc.) on behalf of a logged-in admin./oauth/token,/oauth/revoke,/oauth/userinfo, and the/api/*namespace continue to authenticate with client credentials or bearer tokens and are intentionally not affected. -
The application error handler now returns the response carried by
HTTPExceptioninstead of rethrowing it as a generic 500. Without this, middleware that signals refusal by throwingHTTPException(403, …)(the new CSRF middleware, among others) would have surfaced as opaque 500 responses to clients. -
Incoming
Follow,Like,EmojiReact, andAnnounceactivities from a blocked actor are now silently dropped. Previously a block only flipped auto-approval on incoming follow requests and did nothing for protected accounts, likes, reactions, or announcements—a blocker still saw notifications and timeline entries from the actor they had blocked. -
Pinned the transitive
fast-xml-parserdependency (carried in via the AWS SDK that backs S3 storage) usingpnpm.overrides. v4 consumers now resolve to^4.5.5(fixing the critical entity- encoding bypass and several high-severity parser issues) and v5 consumers resolve to^5.7.0. Each AWS SDK is kept on its expected major version to preserve API compatibility; the single remaining “XMLBuilder unescaped delimiter” moderate advisory is only patched on v5.7.0+ and is not addressed here because forcing AWS SDK v4 consumers onto fast-xml-parser v5 would risk runtime regressions on S3 deployments. -
Hollo now warns at startup whenever
LOG_QUERY=trueis set. The flag causes drizzle-orm to emit every SQL query together with its bound parameter values, which include OAuth access tokens (stored plain in the database), authorization codes, and other secrets; leaving it enabled in production exposes those secrets to anyone with read access to the application logs (or to a downstream collector such as Sentry or a file sink). -
The OAuth PKCE code-challenge check and the OAuth multi-credential client-secret consistency check are now compared in constant time using
crypto.timingSafeEqual. (The primary client-secret authentication path runs as a Postgres equality predicate and is unchanged.) The PKCE comparison is between two SHA-256 hashes (low practical timing-attack risk) and the multi-credential consistency check only fires when a client presents the same credentials via more than one mechanism, so neither was a confirmed exploitation primitive, but constant-time comparison is the correct defence-in-depth posture for any user-space operation on a secret.
Released on May 10, 2026.
- Upgraded Fedify to 1.10.9 to fix a critical SSRF (Server-Side Request Forgery) vulnerability where private IPv4 addresses encoded as IPv6 literals could bypass security checks during remote ActivityPub object fetching.
Released on May 5, 2026.
- Fixed a security vulnerability where the hashtag follow/unfollow API endpoints were missing an ownership filter, allowing a single authenticated request to modify followed tags for all account owners in the database. [#429 by tomaioo]
Released on April 26, 2026.
- Fixed a Mastodon API compatibility regression where replies to local posts
were stored as
statusnotifications, causing clients to show generic “posted” titles instead of reply notifications. Replies are now stored asmentionnotifications. [#380]
Released on April 25, 2026.
- Fixed a federation bug where duplicate Announce activities from the same actor for the same post could fail with a database uniqueness error instead of being treated idempotently. [#443, #444]
Released on April 21, 2026.
- Fixed a security vulnerability where a public profile's Atom feed could expose followers-only posts and direct messages. The Atom feed now only serves public and unlisted posts. [#440]
Released on April 8, 2026.
- Upgraded Fedify to 1.10.8 for performance improvements and interoperability fixes.
Released on March 29, 2026.
-
Reduced the risk of long-running PostgreSQL transactions during federation processing. Federation inbox handlers and remote actor post imports no longer wrap remote post/account persistence in explicit transactions, which could otherwise stay open while fetching remote ActivityPub objects, preview cards, and media attachments. This should reduce
INSERT waitingpile-ups and improve resilience when remote servers are slow or unresponsive. [#411] -
Fixed a bug where timeline markers hadn't allowed partial updates. [#412 by Nicole Mikołajczyk]
-
Fixed a Mastodon API compatibility bug where some serialized statuses had emitted
nullmention URLs or unsupported attachment types, which could break rendering in Moshidon custom lists. Mention URLs now fall back to the account IRI, and unsupported media types are normalized tounknown. [#414]
Released on March 27, 2026.
- Upgraded Fedify to 1.10.5 for security reasons. [CVE-2026-34148]
Released on March 13, 2026.
- Fixed video thumbnail generation failing for some MP4/MOV files by writing
the video data to a temporary file instead of piping it via stdin
(
pipe:0), which does not support seeking. [#397, #398 by NTSK]
Released on March 11, 2026.
-
Fixed a federation interoperability bug where reactions (
LikeandEmojiReact) to remote posts could be ignored when the activityobjectused a remote IRI that did not match Hollo's local URI pattern. Inbox handlers now fall back to resolving posts byposts.iri, so remote self-reactions (e.g., Misskey users reacting to their own remote notes) are persisted and shown correctly in Mastodon-compatible clients. [#394] -
Hardened inbox reaction processing to tolerate duplicate deliveries by making
Like/EmojiReactinserts idempotent, preventing duplicate-key failures during federation retries. -
Upgraded Fedify to 1.10.4.
Released on March 3, 2026.
- Fixed a bug where posts from blocked accounts could still appear in
timeline inboxes (
/api/v1/timelines/homeand list timelines) whenTIMELINE_INBOXESwas enabled. Timeline filtering now consistently excludes blocked accounts, including shared posts and replies related to blocked accounts.
Released on February 24, 2026.
-
Fixed a federation interoperability bug where follow requests to some Bonfire instances could remain pending even after receiving
AcceptorRejectactivities. Inbox follow handlers now fall back to resolving the embeddedFollowobject (withcrossOrigin: "trust") and match by actor when theobjectID does not match Hollo's stored follow IRI. [#373] -
Fixed a bug where the local account's
followingCountwas not updated when anAcceptactivity was processed via the fallback path that resolves the embeddedFollowobject (Path B). The handler was incorrectly passing the accepting actor's account ID toupdateAccountStatsinstead of the local follower's account ID. [#374]
Released on February 23, 2026.
- Temporarily changed Fedify's
firstKnocksetting todraft-cavage-http-signatures-12for outbound inbox deliveries as a compatibility workaround for Bonfire's current signature handling. This is intended to be reverted to Fedify's default RFC 9421-first behavior after the Bonfire fix is released. [bonfire-networks/activity_pub#8]
Released on February 10, 2026.
- Fixed a security vulnerability where DMs and followers-only posts were exposed through the ActivityPub outbox endpoint without authorization. The outbox now only serves public and unlisted posts. Any unauthenticated request to the outbox could previously retrieve all posts regardless of their visibility setting. [CVE-2026-25808]
Released on February 4, 2026.
- Fixed emoji reaction notifications not displaying emoji information in
Mastodon-compatible clients. The
/api/v1/notificationsendpoint now includes top-levelemojiandemoji_urlfields foremoji_reactionnotifications, compatible with Pleroma/Akkoma clients like Phanpy. [#358]
Released on January 24, 2026.
-
Implemented advanced search query operators for the
/api/v2/searchendpoint, enabling Mastodon-compatible search filtering. Supported operators include:has:media/has:poll— Filter by attachmentsis:reply/is:sensitive— Filter by post characteristicslanguage:xx— Filter by ISO 639-1 language codefrom:username— Filter by author (supports@user,user@domain)mentions:username— Filter by mentioned userbefore:YYYY-MM-DD/after:YYYY-MM-DD— Filter by date range- Negation with
-prefix (e.g.,-has:media) ORoperator for alternative matches- Parentheses for grouping (e.g.,
(from:alice OR from:bob) has:poll)
-
Significantly improved
/api/v1/notificationsendpoint performance by implementing a materialized notifications system. The endpoint now uses dedicatednotificationsandnotification_groupstables instead of generating notifications on-demand via complex SQL queries, resulting in approximately 24% improvement (2.5s → 1.9s). Key changes include:- Added
notificationstable to store notification events as they occur during federation activities (follows, likes, mentions, shares, etc). - Added
notification_groupstable for Mastodon-compatible notification grouping and aggregation metadata. - Implemented automatic notification creation in federation inbox handlers for all notification types.
- Backfilled recent notifications (100 per type) during migration to prevent empty notification lists after upgrade.
- Poll expiry notifications are queried dynamically on-demand since they cannot be pre-generated without background job scheduling.
- Added
-
Enabled gzip/deflate compression for all API responses, reducing response sizes by 70–92% and improving overall API performance. For example,
/api/v1/notificationsresponses are now compressed from 767KB to 58KB,/api/v1/timelines/homefrom 91KB to 14KB, resulting in faster load times and reduced bandwidth usage. -
Implemented Mastodon v2 grouped notifications API (
/api/v2/notifications), which provides server-side notification grouping to reduce client complexity and improve performance. The API groups notifications of typesfavourite,follow,reblog,admin.sign_up, andemoji_reactiontogether when they target the same post or account. New endpoints include:GET /api/v2/notifications: Get paginated grouped notifications with deduplicated accounts and statusesGET /api/v2/notifications/:group_key: Get a specific notification groupGET /api/v2/notifications/:group_key/accounts: Get all accounts in a notification groupPOST /api/v2/notifications/:group_key/dismiss: Dismiss a notification groupGET /api/v2/notifications/unread_count: Get unread notification count
-
Fixed
POST /api/v1/statusesandPUT /api/v1/statuses/:idendpoints rejecting FormData requests. These endpoints now properly accept both JSON and FormData content types, improving compatibility with Mastodon clients that sendmultipart/form-datarequests. [#170, #171 by Emelia Smith] -
Fixed a bug where multiple JSON objects were written on a single line in log files when
LOG_FILEenvironment variable was set. Upgraded LogTape to 2.0.0 and now usesjsonLinesFormatterto ensure proper JSON Lines format with one JSON object per line. [#174] -
Fixed
POST /api/v1/statusesendpoint rejecting requests withnullvalues in optional fields. The endpoint now properly acceptsnullvalues for fields likemedia_ids,poll,spoiler_text,in_reply_to_id, and other optional parameters, improving compatibility with Mastodon clients. [#177, #179 by Lee ByeongJun] -
Implemented asynchronous import job processing with a background worker to improve the reliability and performance of account data imports (following accounts, lists, muted/blocked accounts, bookmarks). Large imports no longer block the HTTP request, and users can see real-time progress of their imports. [#94, #295 by Juyoung Jung]
-
Improved instance API responses for better third-party client compatibility. [#296 by Juyoung Jung]
GET /api/v1/instance: Addedconfiguration.accounts.max_featured_tagsfield,thumbnailfield with Hollo logo, and implemented actualstatsvalues (user_count,status_count,domain_count) from the database.GET /api/v2/instance: Addedthumbnailobject withurl,blurhash, andversionsfields,iconarray, and updatedmax_featured_tagsandmax_pinned_statusesvalues from 0 to 10.
-
Fixed OAuth token endpoint rejecting requests from clients that send credentials via both HTTP Basic authentication and request body simultaneously. The endpoint now accepts such requests if the credentials are identical, improving compatibility with clients like tooot. [#296 by Juyoung Jung]
-
Upgraded Fedify to 1.10.0.
-
Added
prevlink to theLinkheader in/api/v1/notificationsAPI responses for Mastodon-compatible pagination. This allows clients to efficiently fetch new notifications since the last received notification, improving caching capabilities and reducing server load. [#312] -
Fixed OAuth token endpoint failing to parse request body when HTTP clients don't send
Content-Typeheader. Some clients like Lobsters' Sponge HTTP client don't setContent-Typefor POST requests with form data, causing authentication failures. The endpoint now correctly parses URL-encoded form data even whenContent-Typeis missing or set totext/plain. -
Implemented Mastodon 4.5.0 quote notification types (
quoteandquoted_update) for improved quote post interaction tracking. Users now receive notifications when their posts are quoted by others and when posts they've quoted are edited by the original authors. Key features include:- Added
quotenotification type that triggers when someone quotes your post, with the notification showing the quote post itself. - Added
quoted_updatenotification type that triggers when a post you quoted is edited, with the notification showing your quote post to provide context. - Both notification types are non-groupable, meaning each quote or edit generates an individual notification for better visibility.
- Self-quotes (quoting your own posts) do not generate notifications to avoid unnecessary noise.
- Existing quote posts are automatically backfilled with notifications during migration to ensure consistent notification history.
- Added database index on
posts.quote_target_idfor improved query performance when looking up quote relationships.
- Added
-
Removed dependency on deprecated fluent-ffmpeg package and now invoke ffmpeg binary directly for video screenshot generation. This change improves reliability by preventing request failures when video screenshot generation encounters errors. On failure, a default screenshot (Hollo logo) is now returned instead of aborting the entire upload request, and ffmpeg error output is logged for debugging. [#333 by Peter Jeschke]
-
Fixed a bug where querying the
/api/v1/notificationsand/api/v2/notificationsendpoints with unknown notification types (e.g.,types[]=reactionfrom clients like Moshidon) resulted in500 Internal Server Errorresponses due to database enum validation failures. The endpoints now filter out unknown notification types before passing them to the database layer, returning an empty result instead of an error. [#334 by Peter Jeschke] -
Fixed a bug where the
/api/v2/searchendpoint did not properly enforce thelimitparameter on search results. The endpoint now correctly limits the number of returned accounts and statuses to the requested limit (default 20, maximum 40), improving Mastodon API compatibility and preventing potential performance issues with large result sets. [#210] -
Significantly improved
/api/v2/searchendpoint performance when searching by URL or handle. The endpoint now responds in approximately 1.4 seconds for URL searches, down from 8–10 seconds previously (approximately 85% improvement). Key optimizations include:- Skip unnecessary
lookupObjectcalls for non-URL/non-handle queries, reducing remote federation lookups by 2–3 seconds. - Skip full-text search on
posts.content_htmlcolumn when the query is a URL and the post is found in cache lookup (by IRI or URL), eliminating expensive table scans that took ~8 seconds. - Added shared
HANDLE_PATTERNregex in src/patterns.ts for consistent WebFinger handle validation across v1 and v2 APIs.
- Skip unnecessary
Released on February 10, 2026.
- Fixed a security vulnerability where DMs and followers-only posts were exposed through the ActivityPub outbox endpoint without authorization. The outbox now only serves public and unlisted posts. Any unauthenticated request to the outbox could previously retrieve all posts regardless of their visibility setting. [CVE-2026-25808]
Released on December 20, 2025.
- Upgraded Fedify to 1.6.15 to fix a ReDoS (Regular Expression Denial of Service) vulnerability in Fedify's HTML parsing code. An attacker could exploit this vulnerability to cause denial of service by sending malicious HTML responses during federation operations. [CVE-2025-68475]
Released on November 15, 2025.
- Reverted the
/api/v1/notificationsendpoint query optimization from 0.6.17 due to a regression that caused server errors when serializing reactions without account information. The optimization attempted to reduce query complexity by separating post data loading, but inadvertently broke reaction serialization for nested posts (shares and quotes). Database indexes added in 0.6.17 are retained.
Released on November 15, 2025.
-
Significantly improved
/api/v1/notificationsendpoint performance by optimizing database queries and restructuring data loading strategy. The endpoint now responds in under 1.6 seconds, down from over 2.5 seconds previously (approximately 40% improvement). Key optimizations include:- Pre-fetching muted and blocked account IDs to eliminate correlated subqueries in notification type queries.
- Separating post data loading into multiple targeted queries instead of using deeply nested lateral joins, reducing query complexity and execution time.
- Adding strategic database indexes on
follows,mutes,likes, andreactionstables to improve query performance.
Released on November 12, 2025.
-
Fixed search functionality not returning any results when searching for post content.
-
Fixed search results including shared posts (reposts/reblogs). Search now shows only original posts and replies, excluding shares.
Released on November 7, 2025.
- Significantly improved
/nodeinfo/2.1endpoint performance by optimizing database queries and adding appropriate indexes. The endpoint now responds in under 1 second even with millions of federated posts, down from 5–15 seconds previously. This prevents load balancer health check failures and external service timeouts. [#282]
Released on October 7, 2025.
- Fixed a critical security vulnerability where direct messages (DMs) were visible to all authenticated users regardless of whether they were participants in the conversation. The visibility filter now correctly restricts direct messages to only the sender and mentioned recipients, preventing unauthorized access to private conversations. [#247, #255 by Hyeonseo Kim]
Released on October 7, 2025.
- Fixed a bug where replies from followers who are not followed back were not visible in conversation threads. The visibility filter now correctly includes posts that mention the authenticated user, ensuring that all replies directed to the user are displayed regardless of follow-back status.
Released on October 4, 2025.
- Fixed a critical security vulnerability where direct messages were leaked on public post pages. The replies list below posts now correctly filters to show only public or unlisted replies, preventing private conversations from being exposed. [#246, #248 by Hyeonseo Kim]
Released on September 17, 2025.
- Fixed a bug where
Likeactivities from Bluesky via BridgyFed were not being received due to invalid AT Protocol URIs. This was resolved by upgrading Fedify to 1.5.9, which includes improved AT Protocol URI handling to properly parse URIs with DID authorities. [#217]
Released on August 26, 2025.
- Upgraded Fedifyh to 1.5.7 which fixes a bug where HTTP Signature
verification failed for requests having
createdorexpiresfields in theirSignatureheader, causing500 Internal Server Errorresponses in inbox handlers.
Released on August 25, 2025.
-
Fixed a bug where ActivityPub Discovery failed to recognize XHTML self-closing
<link>tags. The HTML/XHTML parser now correctly handles whitespace before the self-closing slash (/>), improving compatibility with XHTML documents that follow the self-closing tag format. -
Upgraded Fedify to 1.5.6.
Released on August 21, 2025.
- Fixed a critical bug introduced in 0.6.7 where the search query would return too many results, causing out-of-memory errors and query timeouts. The issue was caused by incorrect logical operator precedence when filtering future-dated posts. [#207, #208 by aliceif]
Released on August 19, 2025.
- Fixed timeline pollution caused by future-dated posts from malicious or misconfigured remote instances. Posts with timestamps more than 5 minutes in the future are now filtered from all timeline endpoints while preserving them in the database for future display. [#199, #201 by Hyeonseo Kim]
Released on August 8, 2025.
- Upgrade Fedify to 1.5.5, which includes a critical security fix CVE-2025-54888 that addresses an authentication bypass vulnerability allowing actor impersonation. [CVE-2025-54888]
Released on July 17, 2025.
- Fixed an HTML injection vulnerability where form elements, scripts, and other potentially dangerous HTML tags in federated posts were not properly sanitized before rendering. This could allow malicious actors to inject forms for phishing, execute JavaScript, or perform CSRF attacks. The fix implements strict HTML sanitization using an allowlist approach to ensure only safe HTML elements and attributes are rendered. [CVE-2025-53941]
Released on July 7, 2025.
-
Fixed a regression bug where follower-only posts were returning
404 Not Founderrors when accessed through conversation threads. This was caused by improper OAuth scope checking that only acceptedread:statusesscope but tokens containreadscope: [#169, #172]GET /api/v1/statuses/:idGET /api/v1/statuses/:id/context
Released on June 23, 2025.
- Fixed a bug where remote posts mentioning the same user multiple times could not be retrieved due to database constraint violations.
Released on June 8, 2025.
- Fixed an issue where Hollo 0.6.x installations upgraded from Hollo 0.5.x or earlier failed to sign in with Elk, a popular Mastodon client. This was caused by old application registrations incorrectly defaulting to non-confidential. All existing applications are now properly set as confidential clients. [#167, #168 by Emelia Smith]
Released on June 5, 2025.
- Fixed
POST /oauth/tokenendpoint rejecting requests with additional parameters not required by RFC 6749 but commonly sent by clients. The endpoint now gracefully ignores extra parameters likescopeinauthorization_coderequests andredirect_uriinclient_credentialsrequests instead of returning validation errors. [#163, #164 by Hong Minhee]
Released on June 5, 2025.
-
Revamped the environment variables for asset storage configuration. [#115, #121 by Emelia Smith]
- Added
FS_STORAGE_PATHenvironment variable, which is required whereDRIVE_DISKis set tofs. - Added
STORAGE_URL_BASEenvironment variable, which is required. - Deprecated
FS_ASSET_PATHin favor ofFS_STORAGE_PATH. - Deprecated
ASSET_URL_BASEin favor ofSTORAGE_URL_BASE.
- Added
-
Implemented OAuth 2.0 Authorization Code flow with support for access grants. This improves the security of the OAuth authorization process by separating the authorization code from the access token issuance. [#130 by Emelia Smith]
-
Hollo now requires the
SECRET_KEYenvironment variable to be at least 44 characters long. This change ensures sufficient entropy for cryptographic operations. [#126 by Emelia Smith] -
Hollo now lets /.well-known/ and /oauth/ endpoints allow cross origin requests which is aligned with those of Mastodon. [#126 by Emelia Smith]
-
Added the
BINDenvironment variable to specify the host address to listen on. [#114, #120 by Emelia Smith] -
The theme color of the profile page is now customizable. The list of all available theme colors can be found in the Colors section of the Pico CSS docs.
-
You can now sign out from the administration dashboard. [#50, #122 by Emelia Smith]
-
On profile page, shared posts are now more visually separated from the original posts, and the time of sharing is now shown. [#111]
-
On profile page, alt texts for images are now expanded within
<details>. [#99, #110 by Okuto Oyama] -
The
scopeparameter is now optional forPOST /oauth/tokenendpoint. -
The current version string is displayed at the bottom of the dashboard page. [#136, #137 by RangHo Lee]
-
Increased the maximum character limit for posts from 4,096 to 10,000 characters.
-
EXIF metadata of attached images are now stripped before storing them to prevent privacy leaks. [#152 by NTSK]
-
Code blocks inside Markdown are now highlighted. The syntax highlighting is powered By Shiki. See also the complete list of supported languages. [#149]
-
Implemented OAuth 2.0 Proof Key for Code Exchange (PKCE) support with the
S256code challenge method. This enhances security by preventing authorization code interception attacks in the OAuth authorization flow. [#155 by Emelia Smith] -
Added support for the
profileOAuth scope for enhanced user authentication. This allows applications to request limited profile information using the new/oauth/userinfoendpoint and enables theprofilescope to be used with theGET /api/v1/accounts/verify_credentialsendpoint. [#45, #156 by Emelia Smith] -
Made few Mastodon API endpoints publicly accessible without authentication so that they behave more similarly to Mastodon:
GET /api/v1/statuses/:idGET /api/v1/statuses/:id/context
-
Upgraded Fedify to 1.5.3 and @fedify/postgres to 0.3.0.
-
The minimum required version of Node.js is now 24.0.0.
Released on August 8, 2025.
- Upgrade Fedify to 1.4.13, which includes a critical security fix CVE-2025-54888 that addresses an authentication bypass vulnerability allowing actor impersonation. [CVE-2025-54888]
Released on April 29, 2025.
-
Fixed a bug where voting to a poll which had been shared (boosted) had not been sent to the correct recipient. [#142]
-
Upgrade Fedify to 1.4.10.
Released on March 23, 2025.
-
Fixed a bug where private replies were incorrectly delivered to all recipients of the original post, regardless of visibility settings.
-
Improved privacy for direct messages by preventing delivery through shared inboxes.
Released on February 26, 2025.
-
Fixed a bug where custom emojis in the display name and bio had not been rendered correctly from other software including Mitra.
-
Upgrade Fedify to 1.4.4.
Released on February 22, 2025.
-
Fixed a bug where when an account profile had been updated, the
Updateactivity had been made with noassertionMethodsfield, which had caused interoperability issues with Mitra. -
Upgrade Fedify to 1.4.3.
Released on February 20, 2025.
-
Fixed a bug where the
follows.follower_idcolumn had not referenced theaccounts.idcolumn. [#112] -
Fixed a bug where
GET /api/v1/notificationshad returned server errors with some filters. [#113] -
Fixed a bug where the federation dashboard had not shown due to server errors when an instance had just been set up.
-
Upgrade Fedify to 1.4.2.
Released on February 14, 2025.
- Fixed a bug where
GET /api/v1/accounts/:id/statuseshad tried to fetch remote posts for local accounts. [#107]
Released on February 12, 2025.
-
The number of shares and likes became more accurate.
- The
Noteobjects now havesharesandlikescollections with theirtotalItemsnumbers. - When a remote
Noteis persisted, now thetotalItemsnumbers ofsharesandlikesare also persisted. - When a
Announce(Note)orUndo(Announce(Note))activity is received, now it is forwarded to the followers as well if the activity is signed.
- The
-
Added
GET /api/v1/mutesAPI to Mastodon comapatiblity layer. This API returns a list of accounts that are muted by the authenticated user. [#103] -
Added
GET /api/v1/blocksAPI to Mastodon comapatiblity layer. This API returns a list of accounts that are blocked by the authenticated user. [#103] -
On profile page, backward pagination (newer posts) is now available. [#104, #105 by Okuto Oyama]
-
On profile page, images are no more captioned using
<figcaption>but use onlyaltattribute for accessibility. [#99, #100 by Okuto Oyama] -
Fixed a style bug where horizontal scrolling occurred when the screen size was reduced when there were many custom fields on profile page. [#106 by Okuto Oyama]
-
Added
ALLOW_HTMLenvironment variable to allow raw HTML inside Markdown. This is useful for allowing users to use broader formatting options outside of Markdown, but to avoid XSS attacks, it is still limited to a subset of HTML tags and attributes. -
On profile page, the favicon is now switched between light and dark mode according to the user's preference. [#101]
-
The
S3_REGIONenvironment variable became required ifDRIVE_DISKis set tos3. [#95]
Released on August 8, 2025.
- Upgrade Fedify to 1.3.20, which includes a critical security fix CVE-2025-54888 that addresses an authentication bypass vulnerability allowing actor impersonation. [CVE-2025-54888]
Released on March 23, 2025.
-
Fixed a bug where private replies were incorrectly delivered to all recipients of the original post, regardless of visibility settings.
-
Improved privacy for direct messages by preventing delivery through shared inboxes.
Released on February 26, 2025.
-
Fixed a bug where custom emojis in the display name and bio had not been rendered correctly from other software including Mitra.
-
Upgrade Fedify to 1.3.11.
Released on February 22, 2025.
-
Fixed a bug where when an account profile had been updated, the
Updateactivity had been made with noassertionMethodsfield, which had caused interoperability issues with Mitra. -
Upgrade Fedify to 1.3.10.
Released on February 20, 2025.
-
Fixed a bug where the
follows.follower_idcolumn had not referenced theaccounts.idcolumn. [#112] -
Fixed a bug where
GET /api/v1/notificationshad returned server errors with some filters. [#113] -
Fixed a bug where the federation dashboard had not shown due to server errors when an instance had just been set up.
-
Upgrade Fedify to 1.3.9.
Released on February 14, 2025.
- Fixed a bug where
GET /api/v1/accounts/:id/statuseshad tried to fetch remote posts for local accounts. [#107] - Upgrade Fedify to 1.3.8.
Released on February 1, 2025.
-
Upgrade Fedify to 1.3.7.
-
Fixed a bug where
LOG_LEVELenvironment variable had not been respected. -
Fixed a bug where when
DRIVE_DISKis set tofsandFS_ASSET_PATHis set to a relative path, Hollo server had failed to start.
Released on January 31, 2025.
-
Fixed a bug where the migration dashboard had not been shown correctly when the aliases of the account contained an actor whose the server was unreachable. [#98]
-
Fixed a bug where Hollo posts had included unintended extra line breaks on Iceshrimp. [#88]
-
Fixed a bug where importing emojis from remote servers had failed when some shortcodes were already in use. [#102]
-
Upgrade Fedify to 1.3.6.
Released on January 21, 2025.
- Upgrade Fedify to 1.3.4, which includes security fixes. [CVE-2025-23221]
Released on January 11, 2025.
- Fixed a bug where mutes with duration had not been expired correctly. [#92]
- Fixed a bug where importing follows from CSV generated by Iceshrimp had failed. [#85]
Released on December 31, 2024.
- Prefer IPv6 to IPv4 addresses when connecting to remote servers.
Released on December 31, 2024.
-
Upgrade Fedify to 1.3.3.
-
Fixed an interoperability issue with GoToSocial.
Released on December 30, 2024.
-
Hollo is now powered by Node.js 23+ instead of Bun for more efficient memory usage.
-
Added an experimental feature flag
TIMELINE_INBOXESto store all posts visible to your timeline in the database, rather than filtering them in real-time as they are displayed. This is useful for relatively larger instances with many incoming posts, but as of now it may have several bugs. It is expected to be the default behavior in the future after it is stabilized. -
Now you can import and export your data from the administration dashboard in CSV format: follows, lists, accounts you muted, accounts you blocked, and bookmarks.
-
You can now make your profile
discoverable. -
The profile page now shows a user's cover image if they have one.
-
Added
GET /api/v1/statuses/:id/reblogged_byAPI to Mastodon comapatiblity layer. This API returns a list of accounts that have shared a post. -
Fixed a bug where a server error occurred when an invalid UUID was input via URL or form data. [#65]
-
Fixed a bug where the same post could be shared multiple times by the same account.
-
Added
LOG_FILEenvironment variable to specify the file path to write structured logs. The logs are written in JSON Lines format. -
Improved the performance of recipients gathering during sending activities.
-
For the sake of concision, now log sink for Sentry is removed.
Released on August 8, 2025.
- Upgrade Fedify to 1.3.20, which includes a critical security fix CVE-2025-54888 that addresses an authentication bypass vulnerability allowing actor impersonation. [CVE-2025-54888]
Released on March 23, 2025.
-
Fixed a bug where private replies were incorrectly delivered to all recipients of the original post, regardless of visibility settings.
-
Improved privacy for direct messages by preventing delivery through shared inboxes.
Released on February 26, 2025.
-
Fixed a bug where custom emojis in the display name and bio had not been rendered correctly from other software including Mitra.
-
Upgrade Fedify to 1.3.11.
Released on February 22, 2025.
-
Fixed a bug where when an account profile had been updated, the
Updateactivity had been made with noassertionMethodsfield, which had caused interoperability issues with Mitra. -
Upgrade Fedify to 1.3.10.
Released on February 14, 2025.
- Fixed a bug where
GET /api/v1/accounts/:id/statuseshad tried to fetch remote posts for local accounts. [#107] - Upgrade Fedify to 1.3.8.
Released on January 21, 2025.
- Upgrade Fedify to 1.3.4, which includes security fixes. [CVE-2025-23221]
Released on December 28, 2024.
-
Fixed a bug where validation check for the account username had not been performed correctly. [#80]
-
Documented the
TZenvironment variable. [#82]
Released on December 20, 2024.
- Fixed a bug where deleting a post had not been propagated to the peers.
Released on December 19, 2024.
- Fixed a bug where generated thumbnails had been cropped incorrectly if the original image had not the EXIF orientation metadata. [#76]
Released on December 18, 2024.
-
Fixed a bug where generated thumbnails had not copied the EXIF orientation metadata from the original image. [#76]
-
Fixed a bug where looking up remote Hubzilla actors and objects had failed. [#78]
-
Upgrade Fedify to 1.3.2.
Released on December 13, 2024.
-
Fixed a bug where
Undo(Like)activities on aQuestionobject had not been handled correctly. -
Fixed a bug where
EmojiReactactivities on aQuestionobject had not been handled correctly. -
Fixed a bug where
Undo(EmojiReact)activities on aQuestionobject had not been handled correctly.
Released on December 1, 2024.
-
Added support for local filesystem storage for media files. You can now configure
DRIVE_DISK=fsandFS_ASSET_PATHto store media files in the local filesystem. [#59]- Added
DRIVE_DISKenvironment variable. - Added
FS_ASSET_PATHenvironment variable. - Added
ASSET_URL_BASEenvironment variable to replaceS3_URL_BASE. - Deprecated
S3_URL_BASEenvironment variable in favor ofASSET_URL_BASE.
- Added
-
Added support for Sentry.
- Added
SENTRY_DSNenvironment variable.
- Added
-
Added pagination to the profile page. [#40]
-
Upgrade Fedify to 1.3.0.
Released on December 13, 2024.
-
Fixed a bug where
Undo(Like)activities on aQuestionobject had not been handled correctly. -
Fixed a bug where
EmojiReactactivities on aQuestionobject had not been handled correctly. -
Fixed a bug where
Undo(EmojiReact)activities on aQuestionobject had not been handled correctly.
Released on November 22, 2024.
-
Fixed a bug where followees and followers that had not been approved follow requests had been shown in the followees and followers lists.
-
Fixed a bug where followees and followers had been listed in the wrong order in the followees and followers lists. [#71]
-
Upgrade Fedify to 1.2.7.
Released on November 7, 2024.
- Fixed a bug where replies without mention had not shown up in the notifications. [#62]
Released on November 4, 2024.
- Fixed a bug where posts from some ActivityPub software (e.g., Misskey,
Sharkey, Akkoma) had empty
urlfields, causing them to be displayed incorrectly in client apps. [#58]
Released on November 3, 2024.
-
Dropped support for Redis.
-
Added two-factor authentication support. [#38]
-
Custom emojis now can be deleted from the administration dashboard.
-
Renamed the Data menu from the administration dashboard to Federation.
- Now posts also can be force-refreshed.
- Now the number of messages in the task queue is shown.
-
Added support for reporting remote accounts and posts. [#41 by Emelia Smith]
-
Improved alignment on Mastodon API changes about OAuth and apps. [#43 by Emelia Smith]
GET /api/v1/apps/verify_credentialsno longer requiresreadscope, just a valid access token (or client credential).POST /api/v1/appsnow supports multiple redirect URIs.redirect_uriis deprecated, but software may still rely on it until they switch toredirect_uris.- Expose
redirect_uri,redirect_uris, andscopesto verify credentials for apps.
-
Added support for RFC 8414 for OAuth Authorization Server metadata endpoint. [#47 by Emelia Smith]
-
On creating a new account, the user now can choose to follow the official Hollo account.
-
Added a favicon.
-
Added
PORTandALLOW_PRIVATE_ADDRESSenvironment variables. [#53 by Helge Krueger]
Released on November 4, 2024.
- Fixed a bug where posts from some ActivityPub software (e.g., Misskey,
Sharkey, Akkoma) had empty
urlfields, causing them to be displayed incorrectly in client apps. [#58]
Released on October 30, 2024.
-
Fixed a bug where followers-only posts from accounts that had had set their follower lists to private had been recognized as direct messages. Even after upgrading to this version, such accounts need to be force-refreshed from the administration dashboard to fix the issue.
-
Fixed the federated (public) timeline showing the shared posts from the blocked or muted accounts.
-
Fixed the list timeline showing the shared posts from the blocked or muted accounts.
Released on October 30, 2024.
- Fixed the profile page showing the shared posts from the blocked or muted accounts.
Released on October 30, 2024.
- Fixed the home timeline showing the shared posts from the blocked or muted accounts.
Released on October 27, 2024.
- Fixed incorrect handling of relative path URIs in
Linkheaders withrel=alternate. This caused inoperability with some software such as GoToSocial. - It now sends
Delete(Person)activity to followees besides followers when a user deletes their account.
Released on October 24, 2024.
- Fixed the last page in the profile using Moshidon leading to infinite pagination. [#48 by Emelia Smith]
Released on October 24, 2024.
- Upgrade Fedify to 1.1.1.
Released on October 22, 2024. Initial release.