Blog

  • Fix Joomla Browser Compatibility Issues

    Fix Joomla Browser Compatibility Issues

    A Joomla browser compatibility issue is a page that works in one current browser and fails in another. On Joomla 4, 5, and 6 the supported browsers are current Chrome, Edge, Firefox, and Safari. Internet Explorer is not supported. A layout that breaks at the same width in every browser is a responsive CSS problem, not a browser bug.

    Most tickets that get called “compatibility” are a cached stylesheet, a browser extension, a template that still targets Joomla 3, or a cookie scoped to the wrong host. Start with the console and a private window. Do not add HTML5 Shiv or Respond.js.

    What you will learn

    • Which browsers Joomla 3, 4, 5, and 6 actually support
    • How to tell a browser bug from a responsive bug, a cache, or an extension
    • Why Internet Explorer cannot be patched back into Joomla 5 or 6
    • The Safari login failure that is really the site URL
    • When the template is the product you need to replace

    Supported browsers

    Joomla Browsers to test Do not spend time on
    3.10 Current Chrome, Edge, Firefox, Safari. The old project list still names Internet Explorer, and that list is not a 2026 requirement IE8, IE9, IE10. Joomla 3 itself is end of life
    4 Current Chrome, Edge, Firefox, Safari. The admin and Cassiopeia use Bootstrap 5 Internet Explorer 11. Bootstrap 5 does not support it
    5 and 6 The same four, current versions. Core JavaScript is modern (ES2018). Joomla 5 stopped shipping the old IE11 script builds IE11, and any plan to load es5.js shims for it

    Bootstrap’s own rule, which Joomla’s UI follows, is the latest stable browsers, not Internet Explorer: Bootstrap browsers and devices. The drop of the IE11 bundles is recorded in the Joomla 4.4 to 5 removal list. The page Joomla Browser Support is a Joomla 3 document. Do not use it as the matrix for Joomla 5 or 6.

    Name the failure before you edit CSS

    What you see In which browsers What it usually is
    Layout wrong only on a phone width All of them Responsive CSS or a missing viewport. Not a browser bug
    IE11 admin is unstyled or dead IE only Unsupported. Move the user to Edge
    One browser shows yesterday’s CSS One Cache, or a service worker
    Styles missing everywhere All CSS 404, mixed content, or .htaccess. See 500 on mod_rewrite
    Login works in Chrome, drops in Safari Safari Site URL, www versus apex, or HTTP versus HTTPS. Cookie scope, not WebKit
    A slider or menu dies in one browser One An extension script. Read the console
    Only the administrator is broken One or all Atum, or an admin module. The site template is innocent
    Blank page, no layout talk All A PHP fatal, not CSS. Read the host log

    Step 1: Write down the browser, the version, and the URL

    1. Note the browser name and a major version (Chrome 131, Safari 18, Firefox ESR). “Doesn’t work on Mac” is not a report.
    2. Note the exact URL. Site homepage, one article, and /administrator/ are three different products.
    3. If the browser is Internet Explorer, stop. On Joomla 4, 5, or 6 that is expected. Send the user to current Edge, Chrome, Firefox, or Safari.
    4. If every current browser fails the same way, you are not debugging compatibility. Fix the error, the missing file, or the template, then come back.

    Step 2: Rule out cache and extensions

    1. Open a private window with extensions disabled. Retest the same URL.
    2. If the private window is fine, the cause is a cached file or an extension (ad blockers often block scripts and fonts). Clear that browser’s cache for the site. Then clear Joomla’s cache (System → Maintenance → Clear Cache) and any CDN.
    3. If the private window is still broken, the site is serving the failure. Continue.

    A hard refresh in one browser does not clear another browser’s cache. That is why “it works on my machine” survives for weeks.

    Step 3: Read the console, not the homepage

    1. Open developer tools in the broken browser. Console and Network.
    2. Reload. Copy the first red error. The file name is the extension or the template.
    3. On Network, filter CSS and JS. A red row is a 404 or a blocked mixed-content request. An unstyled page with a 404 on template.css is a path problem, not a rendering engine.
    4. Mixed content (HTTPS page calling http:// assets) is blocked hardest by Chrome and modern Safari. Fix the URLs in the template. Do not tell users to allow insecure content.

    Step 4: See if the template is the only broken piece

    1. On a staging copy, set the site template to Cassiopeia (System → Site Templates).
    2. Retest the broken browser.
    3. If Cassiopeia is fine, your template or one of its overrides is the bug. Update it to a build for this Joomla major, or replace it. Joomla 3 templates (Bootstrap 2, IE conditional comments, MooTools menus) will not become compatible by adding a script.
    4. If Cassiopeia fails too, the template is not the cause. Look at modules on that page.

    Confirm the template prints a viewport tag. Cassiopeia does. A custom index.php that omits it makes phones look “broken in Safari” while the desktop looks fine:

    <meta name="viewport" content="width=device-width, initial-scale=1">

    Step 5: Disable the extension named in the console

    The first console line usually names a file under /media/, /templates/, /modules/, or /plugins/. Disable that extension on staging and reload.

    • A menu or slider that calls MooTools or an ancient jQuery will fail in current browsers even when the rest of the page is fine. Background: remove MooTools from Joomla.
    • Do not “fix” it by loading jQuery again. Joomla 4, 5, and 6 core UI does not need jQuery. A second copy fights over $ and creates a new one-browser failure.
    • HTML5 Shiv and Respond.js were IE8 hacks. They do nothing useful on Joomla 4+ and they add a script current browsers do not need. Remove them if a ten-year-old tutorial put them in the template.

    Step 6: Fix Safari login separately from CSS

    If the page looks right in Safari but login or the administrator session dies, stop comparing stylesheets.

    1. Global Configuration → Site → Site URL, and the live host, must be the same scheme and host. https://example.com and https://www.example.com are different cookie hosts. Chrome is more forgiving of the redirect. Safari drops the session.
    2. Force one host in the server redirect, then clear cookies and test again.
    3. If the Joomla page is inside an iframe on another site, Safari blocks that cookie. Do not embed the login.

    Step 7: Retest the four current browsers

    • Chrome or Edge (same engine, still check Edge once if the client uses it)
    • Firefox, including ESR if the client is a locked office build
    • Safari on a Mac or an iPhone. Desktop Chrome does not stand in for iOS Safari
    • The administrator, not only the homepage

    A paid cross-browser lab is optional after the console is clean. It is not the first step, and it will not make Internet Explorer run Joomla 6.

    Do not sniff the browser

    Joomla’s old browser class, and any template switch based on the user-agent string, will mislabel current Edge, Brave, and in-app webviews. Serve one template. Fix the CSS. User-agent hacks are how a site ends up with a broken stylesheet that only one browser ever loads, which then looks exactly like a compatibility bug.

    When the honest fix is an upgrade

    If the site is Joomla 3 and the goal is “works in current Safari and Chrome”, Protostar and a pile of IE scripts are the wrong project. Move to a Joomla 5 or 6 template built on Bootstrap 5, on staging, then retest. Path notes: Joomla upgrade issues. Infyways runs those jumps from $149, with a compatibility audit within 12 hours: Joomla Upgrade Services.

    Key takeaways

    1. Joomla 4, 5, and 6 support current Chrome, Edge, Firefox, and Safari. Not Internet Explorer.
    2. Same failure in every browser is not a browser bug.
    3. Private window first, then the console, then Cassiopeia, then the extension named in the error.
    4. Safari login failures are usually the site URL and cookies.
    5. Do not add HTML5 Shiv, Respond.js, or a second jQuery.
    6. A Joomla 3 template will not become compatible by hiding the IE comments. Upgrade the template with the CMS.

    Frequently asked questions

    Which browsers does Joomla support?

    For Joomla 4, 5, and 6, test current Chrome, Edge, Firefox, and Safari. Internet Explorer is not supported. The old Joomla 3 browser list is not the matrix for current releases.

    Why does the site look fine in Chrome and broken in Safari?

    Check a private window, then the console. If only login fails, compare the Global Configuration site URL with the host Safari is using, including www and HTTPS.

    Why is the administrator broken in Internet Explorer?

    Joomla 4 and newer use Bootstrap 5 and modern JavaScript. IE11 is outside that support. Use Edge or another current browser.

    Will HTML5 Shiv or Respond.js fix it?

    No. Those scripts patched Internet Explorer 8. They do not fix Joomla 4, 5, or 6, and they should come out of the template.

    The layout breaks on phones but not on desktop. Is that a browser bug?

    No. If every browser breaks at the same width, it is responsive CSS or a missing viewport tag.

    One browser still shows the old design after I changed the template. Why?

    That browser cached the CSS. Test in a private window, then clear Joomla cache and the CDN.

    Should I load jQuery so older browsers work?

    No. Extra jQuery copies cause $ conflicts. Current Joomla does not need jQuery for the core layout.

    Does Cassiopeia work in all browsers?

    It works in the browsers Joomla supports. Use it as the control. If Cassiopeia is fine and your template is not, fix or replace the template.

    Who can fix a template that only fails in one browser?

    Infyways traces the console error and upgrades templates that cannot be patched. Request a Joomla upgrade audit.

  • Remove the Joomla Generator Meta Tag

    Remove the Joomla Generator Meta Tag

    The Joomla generator meta tag is a single line in the HTML head, <meta name="generator" content="Joomla! - Open Source Content Management">. Joomla adds it in the document class. There is no switch for it in Global Configuration on Joomla 3, 4, 5, or 6. Remove it with setGenerator('') before the head is rendered, or with a system plugin. An empty string omits the tag. null is the wrong value and can fatal on PHP 8.

    The tag does not contain your version number. Removing it does not change Google rankings. It only drops one fingerprint. RSS feeds, the administrator login page, and administrator/manifests/files/joomla.xml still identify the CMS unless you handle those separately.

    What you will learn

    • The exact tag Joomla prints, and why it is not a version number
    • How to see it in HTML and in RSS
    • The template one-liner, and why it disappears on the next template update
    • Why setGenerator(null) is unsafe
    • What still gives the site away after the tag is gone

    What the tag is

    HTML’s generator meta names the software that built the page. Joomla sets that string when it creates the HTML document. It is not read from a menu item, not stored in the database, and not a language string you can override. The same property is written into RSS and Atom as a <generator> element.

    On current Joomla 3.10, 4, 5, and 6 the content is only:

    <meta name="generator" content="Joomla! - Open Source Content Management">

    Very old releases (Joomla 1.5 and early 2.5) put the version in that string. That stopped years ago. If a scanner claims it learned “Joomla 3.9.28” from this meta tag, it learned it somewhere else.

    What removing it does, and what it does not

    Claim Reality
    Hides the Joomla version from attackers The version is not in this tag. It is in administrator/manifests/files/joomla.xml and in the administrator’s System Information screen
    Improves Google rankings No. Google does not use meta name="generator" as a ranking signal
    Hurts SEO No, as long as you do not also delete the robots meta tag
    Makes the site invisible to scanners No. /media/system/js/core.min.js, /administrator/, and Cassiopeia paths still look like Joomla
    Removed by a Joomla or template update if you only edited index.php Yes. A template update replaces that file
    Removed from RSS if you only call setGenerator inside <head> after the head include No. Feeds never render that head block

    Treat this as housekeeping, not as a security patch. An outdated Joomla site with the tag removed is still outdated. Update path: how to update Joomla.

    Step 1: See the tag before you change anything

    1. Open the public homepage.
    2. View source (not only the inspector). Search for generator.
    3. You should find the meta line above. Joomla 3 often writes it self-closed (/>). Joomla 4 and newer usually do not.
    4. Open the feed: add ?format=feed&type=rss to the site URL, or use the RSS link in the page. Search for <generator>. The same sentence is there.
    5. Optional: open /administrator/ and view source. The login page carries the tag too.

    If the line is missing already, a plugin or the template is stripping it. Do not add a second strip until you know which one.

    Step 2: Prefer a plugin over a template edit

    A system plugin runs on every HTML and feed response and survives template updates. Infyways publishes Remove Meta Generator for this. Version 1.4 is for Joomla 4, 5, and 6. It clears or replaces the generator on the public site, can clean RSS and Atom, and can drop the X-Powered-By header. It does not touch the administrator. Listing: Joomla Extensions Directory.

    1. Install the zip and enable System – Remove Meta Generator.
    2. Set generator to remove, or replace it with your own brand text if you want a tag with different content.
    3. Leave the robots option alone unless you have a reason to change indexing. Deleting meta name="robots" can drop a noindex you still need, or strip a normal index directive.
    4. Clear Joomla cache and any CDN cache.
    5. View source on the homepage and on one article. Then check the RSS feed.

    Joomla 3 is not a target of the 1.4 build. On 3.10 use the template line in the next step, or stay on a plugin build that still lists Joomla 3.

    Step 3: Or set an empty generator in the template

    This works on Joomla 3, 4, 5, and 6. In templates/YOUR_TEMPLATE/index.php, before <jdoc:include type="head" /> and before <jdoc:include type="metas" />:

    <?php
    $this->setGenerator('');
    ?>

    Use an empty string. Do not pass null. The document API types setGenerator as a string. On PHP 8 a null argument becomes a fatal once that type is enforced. An empty string is what makes the renderer skip the tag. Joomla only prints the meta when getGenerator() is non-empty.

    Put the line at the top of the file if you are unsure. Code after the head include is too late: the meta block has already been built.

    A template update overwrites index.php. Put the line in a child template, or use the plugin. Do not edit libraries/src/Document/HtmlDocument.php or libraries/joomla/document/html/html.php. The next Joomla update puts the tag back and can break the core file.

    Step 4: Cover feeds, not only the homepage

    The template line never runs for format=feed. A plugin event does. This is the body of a system plugin method. On Joomla 3.8 and newer, and on 4, 5, and 6, Joomla\CMS\Factory is available without the compatibility plugin:

    public function onBeforeRender()
    {
        $app = Factory::getApplication();
    
        if (!$app->isClient('site')) {
            return;
        }
    
        $doc = $app->getDocument();
        $type = $doc->getType();
    
        if ($type !== 'html' && $type !== 'feed') {
            return;
        }
    
        $doc->setGenerator('');
    }

    onBeforeRender is early enough for HTML and for RSS. onBeforeCompileHead is HTML-only, so a head-only hook leaves the feed element in place. Skip non-HTML types such as JSON and raw so you do not touch component output that is not a document head.

    On Joomla 3.7 and older, swap Factory::getApplication() for JFactory::getApplication() and isClient('site') for isSite().

    Step 5: Confirm it is gone, including cache

    • View source on the homepage, an article, and a category blog.
    • Search for name="generator". No match means the Joomla tag is gone. A match with different content means a template or extension hardcoded its own tag. setGenerator will not delete a string that was echoed by hand. Search the template for generator and remove that line.
    • Open the RSS URL and confirm there is no <generator>Joomla! element, if you used the plugin or onBeforeRender.
    • Clear System → Maintenance → Clear Cache, then the host cache or Cloudflare, or you will keep seeing the old HTML.
    • Check /administrator/ only if you intended to change it. The JoomlaX plugin leaves admin pages alone on purpose.

    Other fingerprints people confuse with this tag

    Signal What it is Removed by setGenerator?
    meta name="generator" HTML fingerprint, no version Yes, if you set an empty string in time
    RSS <generator> Same property, feed renderer Only if the call runs for feed documents
    X-Powered-By: PHP/x.y Server header, not Joomla’s meta tag No. Turn it off in PHP or in the plugin’s header option
    administrator/manifests/files/joomla.xml Core manifest, includes the version No. This file is the real version leak
    /media/system/js/core.min.js and /administrator/ Paths and the login screen No
    meta name="robots" Indexing instructions Should stay. Unrelated to the generator

    Blocking the manifest is a hosting or Admin Tools job, not a meta-tag job. Hiding files is still weaker than installing updates. If the site is on Joomla 3, plan the move instead of collecting hide-the-CMS tricks: Joomla upgrade services.

    SEO

    Removing the generator tag does not move rankings. Google indexes the visible page, links, and a handful of meta tags it actually reads (description, robots). generator is not one of them. More on what does matter: Joomla SEO.

    The change that does hurt SEO is a plugin option that deletes every robots meta. Leave that control on “leave” unless you are setting a specific policy, such as index, follow on purpose.

    Key takeaways

    1. The tag says Joomla. It does not say which version.
    2. There is no Global Configuration checkbox. Use setGenerator('') or a plugin.
    3. Never pass null. Never edit files under libraries/.
    4. A template edit dies on the next template update and never touches RSS.
    5. Removing the tag does not change SEO. Do not remove the robots meta while you are there.
    6. Update Joomla. Hiding the tag is not a substitute.

    Frequently asked questions

    How do I see the Joomla generator meta tag?

    View source on the homepage and search for generator. The default content is Joomla! - Open Source Content Management. The same text is in the RSS <generator> element.

    How do I remove the Joomla meta generator from the head?

    Call $this->setGenerator('') in the template before the head include, or enable a system plugin that does it on onBeforeRender. Empty string, not null.

    Will removing the generator tag affect SEO?

    No. Google does not use that meta tag for ranking. Leave meta name="robots" in place.

    Does this tag reveal my Joomla version?

    Not on Joomla 3.10, 4, 5, or 6. The version is in administrator/manifests/files/joomla.xml, not in the generator meta.

    Does Joomla 5 or 6 still add the tag?

    Yes. There is still no core switch. The same setGenerator('') call works, or use Remove Meta Generator 1.4.

    Will a Joomla update put the tag back?

    A core update does not restore a plugin setting. A template update does restore index.php if you edited the parent template. Core file hacks under libraries/ are overwritten.

    Does the template line remove it from RSS?

    No. Feeds do not load index.php. Use onBeforeRender or a plugin that cleans feed output.

    Is setGenerator(null) safe on PHP 8?

    No. Pass an empty string. Null does not match the string argument and can fatal.

    Can I remove it without editing files?

    Yes. Install Remove Meta Generator, enable it, clear cache, and view source.

  • Fix Call to a member function setState() in Joomla

    Fix Call to a member function setState() in Joomla

    Call to a member function setState() on null (also “on bool”, “on boolean”, or “on a non-object”) means Joomla tried to call setState() on a model that was never created. getModel(), JModelLegacy::getInstance(), or createModel() returned false or null, and the next line did not check. This is not a session error, and clearing the cache does not create the missing class.

    The line that dies is almost always a content module or an old component controller preparing a list query. The fix is to load the model, or to update or disable the extension named in the stack trace.

    What you will learn

    • What setState() does on a Joomla model, and why this is not React and not the session
    • Why the same bug is worded three different ways on PHP 7 and PHP 8
    • How to read the file path and name the extension in one minute
    • The Joomla 3 include-path failure, and the Joomla 4, 5, and 6 bootComponent() pattern
    • What to do when the administrator will not open

    What the error actually means

    Joomla list screens do not read $_GET inside the query. They park filters on the model first:

    $model->setState('filter.published', 1);
    $model->setState('list.limit', 5);
    $model->setState('params', $params);
    $items = $model->getItems();

    setState() only exists on a model object (ListModel, BaseDatabaseModel, and the older JModelLegacy). If $model is false or null, PHP stops with a fatal error before getItems() runs. The message changes with the PHP version, not with the bug:

    What PHP says What $model is Typical PHP
    on a non-object false from getInstance() or getModel() PHP 5
    on boolean Same false PHP 7
    on bool Same false PHP 8 and newer
    on null createModel() found nothing PHP 7.0+ and Joomla 4+

    A different sentence, Call to undefined method ... setState(), means you do have an object, but it is the wrong class. Do not mix those up. This article is only the null or false case.

    This is not the session, and it is not React

    Session data in Joomla is $app->setUserState() and getUserState(). Deleting files in /tmp, logging out, or emptying #__session does not make getModel() return an object. Do that only when the error text actually names the session handler.

    React’s setState() is a JavaScript method on a component. A PHP fatal in a .php file under modules or components has nothing to do with a React build. If the stack trace is a .js bundle, you are in a different app that happens to be hosted beside Joomla.

    Where it breaks

    Path in the error What failed Fix
    modules/mod_articles_latest, mod_articles_category, mod_articles_news, mod_related_items The articles model was not booted before setState('params') Use the core helper pattern below, or replace a cloned module
    components/com_SOMETHING/controller.php or controllers/cpanel.php $this->getModel() returned false, then the controller called setState anyway Update that component. Pass the model name. Check the return value
    administrator/components/com_SOMETHING Same failure, backend only Disable that admin component. The public site can stay up
    libraries/legacy/controller or libraries/src/MVC/Controller Core ran. The component in the URL did not provide a model Read option=com_... in the URL. Fix that extension, not the library
    templates/YOUR_TEMPLATE/html An override copied an old helper Compare it with the current core file and drop the stale copy

    The classic core case was Joomla 3.5.0: mod_related_items/helper.php line 44 called setState() on false because com_content models were not on the lookup path. That was fixed in 3.5.1. The report is still the best illustration of the bug: Related Articles module fatal error. Third-party modules still copy the broken pattern.

    Step 1: Get the file and the line

    1. If the page is a blank 500, open the host PHP error log or administrator/logs/. The fatal is one line: message, file, line number.
    2. On a staging copy you can set Global Configuration → Server → Error Reporting to Maximum. Turn it off again on production. Do not leave display_errors on a public site.
    3. Copy the first fatal only. Later errors are fallout.
    4. A white page with no setState text may be .htaccess instead. Check that only after the log is silent. Guide: Joomla 500 on mod_rewrite.

    Step 2: Confirm the variable is empty

    Open the file at the line number. You want a call shaped like one of these:

    • $model->setState(
    • $this->getModel()->setState(
    • $defaultModel->setState(

    Look up three to ten lines. The assignment is getInstance, getModel, or createModel. There is no if (!$model) before setState. That missing check is the crash. Adding a return when the model is empty stops the fatal. It does not by itself bring the module back. You still have to make createModel succeed.

    Step 3: Name the extension from the path

    • mod_ prefix: a module. Unpublish that module to confirm the homepage returns. System → Manage → Extensions, or published = 0 on that row in #__modules if you cannot log in.
    • com_ prefix: a component. The menu item or the URL option= is what triggers it. Note the folder name before you disable anything.
    • plg_ or plugins/: a plugin. Rename that plugin’s folder over FTP if the administrator is already dead.
    • Path contains libraries/joomla or libraries/src and your Joomla version is current: core is the messenger. The broken model belongs to the component in the request.

    Take a backup before you rename folders or edit PHP. Method: how to backup a Joomla website.

    Step 4: Load the articles model the way core does now

    On Joomla 4, 5, and 6, article modules boot the component, then set state. This is the current core pattern in Latest Articles:

    $model = $app->bootComponent('com_content')
        ->getMVCFactory()
        ->createModel('Articles', 'Site', ['ignore_request' => true]);
    
    if ($model === null) {
        return [];
    }
    
    $model->setState('params', $app->getParams());
    $model->setState('filter.published', 1);
    $model->setState('list.limit', (int) $params->get('count', 5));

    $app is Factory::getApplication(). ignore_request stops the model from reading the page URL as its own filters, which is what you want inside a module. Core reference: ArticlesLatestHelper.php.

    If createModel still returns null, com_content is missing, half-updated, or the model name is wrong. Reinstalling random core files is not the first move. Confirm components/com_content exists and that System → Maintenance → Database shows no schema errors. A partial update leaves new PHP calling old tables, or the reverse. Update path: update Joomla and fix update errors.

    Step 5: Fix the Joomla 3 version of the same bug

    Joomla 3 will not boot a component. You add the model folder, then ask for the class prefix ContentModel:

    JModelLegacy::addIncludePath(
        JPATH_SITE . '/components/com_content/models',
        'ContentModel'
    );
    
    $model = JModelLegacy::getInstance(
        'Articles',
        'ContentModel',
        array('ignore_request' => true)
    );
    
    if (!$model) {
        return array();
    }
    
    $model->setState('params', $params);

    The file on disk must be components/com_content/models/articles.php and the class must be ContentModelArticles. A renamed class returns false from getInstance, and the next setState is this fatal.

    Do not paste the Joomla 3 block into Joomla 4, 5, or 6. JModelLegacy is legacy. On current Joomla the failure mode changes: either the class is missing (see class not found after an upgrade) or getInstance returns false and you are back to setState() on bool. Use bootComponent().

    Step 6: Update or disable the extension in the trace

    If the file sits in a commercial component, you cannot invent its model name from the articles example. The controller is calling $this->getModel() with no name, the default model file is gone or not autoloaded after a Joomla 3.10 or Joomla 4 hop, and setState runs on false. That is an extension bug.

    • Update it to a build that lists your Joomla major.
    • If there is no update, disable it and unpublish its modules and menu items.
    • Do not edit libraries/ to hide the message. The next core update overwrites the library and the fatal returns.
    • A template override of a module helper is a copy. Delete the override and let the current module file run. Then retest.

    Major-version breakage of this kind is covered in Joomla upgrade issues. Hop order still matters. A Joomla 3 controller will not start loading models correctly just because the site folder was copied onto Joomla 5.

    Step 7: Clear cache after the page renders

    Module HTML is often cached. A cached fatal, or a cached empty module, can linger after you fix the PHP. Clear it only once the uncached page works:

    1. System → Maintenance → Clear Cache, or the cache button on the module.
    2. Clear the host or CDN cache if the HTML is stored there.
    3. Reload the page that crashed. The log line for setState should be gone.

    If you clear cache first and the model is still null, the error comes straight back. Cache was never the cause.

    Step 8: Get the administrator back

    1. Read the log. If the path contains /administrator/components/com_ or /plugins/, rename that one folder via FTP or the host file manager. Joomla skips an extension whose folder is missing.
    2. If a site module crashes every admin page because it is assigned to the admin menu, unpublish it in #__modules (published set to 0). Match module to the mod_ name from the log.
    3. Leave com_content, com_users, and com_login in place. Renaming those locks you out for a different reason.
    4. When the administrator loads, update or uninstall the extension properly, then restore the folder name only if you still need it.

    What a correct call looks like

    Core always sets state after it knows the model exists. The states you will see in article modules are the query, not user session keys:

    • params: component or module parameters
    • filter.published, filter.category_id, filter.access, filter.language, filter.featured
    • list.start, list.limit, list.ordering, list.direction

    If your code sets those on a model that failed to load, fix the load. If your code sets them on $app, you wanted setUserState() and you are in the wrong API.

    When to stop patching the module

    Stop if any of these are true:

    • The trace names a component you cannot update, and the site still runs Joomla 3
    • Several modules fatal with the same createModel null after a half-finished upgrade
    • You already renamed folders and you are not sure which ones the business needs

    Infyways runs those repairs and version jumps from $149, with a compatibility audit within 12 hours. Start at Joomla Upgrade Services.

    Key takeaways

    1. setState() on null or bool means the model object was never created.
    2. It is not the session, not React, and not fixed by emptying /tmp.
    3. The file path is the extension name. Start there.
    4. Joomla 4, 5, and 6 load article models with bootComponent('com_content') and createModel('Articles', 'Site').
    5. Joomla 3 needs addIncludePath plus ContentModelArticles. Check getInstance before setState.
    6. Clear cache after the page renders, not before.

    Frequently asked questions

    What does Call to a member function setState() mean in Joomla?

    PHP called setState() on null or false. In Joomla that value was supposed to be a model from getModel(), getInstance(), or createModel().

    Is this a session or login error?

    No. Session storage uses setUserState(), which is a different method. Logging out or deleting /tmp does not load a missing model.

    Why does it say on bool on one site and on null on another?

    Same failure. getModel() and getInstance() return false, so PHP 8 says “on bool”. createModel() returns null, so PHP says “on null”.

    Which file should I open?

    The file and line in the error. That line is the setState call. The extension folder in that path is what you update or disable.

    Will Clear Cache fix it?

    No. Clear cache only after the model loads, so Joomla does not keep serving a cached copy of the crash.

    Does Joomla 5 or 6 still use setState()?

    Yes. Article modules still call $model->setState() after createModel('Articles', 'Site'). The method is fine. A null model is not.

    Can I fix it by reinstalling Joomla core?

    Only when the trace points at a core file that does not match a stock copy of your version. If the path is a third-party component, reinstalling core leaves the bug in place.

    The administrator is a white screen. How do I get in?

    Rename the plugin or admin component folder named in the log. Do not rename com_login or com_users. Unpublish a site module from #__modules if that module is what crashes.

    Who can fix setState() fatals across an upgrade?

    Infyways traces the model load and finishes the version jump when the extension has no update. Request a Joomla upgrade audit.

  • Joomla Module Not Showing: Complete Troubleshooting Guide

    Joomla Module Not Showing: Complete Troubleshooting Guide

    A Joomla module is not showing when the module row is not allowed to render for that request: Status is not Published, Access or Language excludes the visitor, Menu Assignment is No pages (or the ticks do not include this Itemid), publishing dates are outside now, or cache still holds an empty slot. A Note in the module list is not a status. This article is that checklist. It is not position wiring (name vs jdoc). It is not “the module appears, but on the wrong pages.”

    If Status, Access, Language, Assignment, and dates are already correct and the region is still empty on every page that uses this template, stop here and open Joomla module position not showing. If the module shows, just not where you meant, open Joomla module showing on the wrong pages. Official assignment help: How do you assign a module to specific pages? and Module display by menu item. Site module overview: Site Modules.

    Unpublished status, access lock, publishing dates, and language

    Published is not enough. Access, Language, Menu Assignment, Start and Finish dates, and cache each get a veto. A Note in the list is only an admin reminder.

    What you will learn

    • How to read Status versus the Note column
    • Why a Super User still “proves nothing” until you test as a guest
    • What Menu Assignment No pages does (without the full wrong-pages deep dive)
    • How Language Filter hides a module that is Published
    • How Start Publishing and Finish Publishing hide a Published module
    • When module cache or Page Cache makes a fixed module look missing
    • When to hand off to the position article (and when not to)
    What you see Likely cause Wrong rabbit hole
    Missing everywhere, including Home Unpublished, Trashed, No pages, dates, or Access Reinstalling the module type
    Missing for guests, visible when you are logged in Access is Registered (or higher) Position names
    Missing in one language Module Language is not All / not that language CSS
    Missing only after a date you set Finish Publishing passed, or Start is still in the future Cache only
    You “fixed it,” guests still see empty Page Cache or Progressive module cache Editing index.php
    Empty slot, ?tp=1 shows the position name Position wiring or chrome/CSS This article’s Status toggles
    Module HTML in View Source, invisible on screen Chrome or CSS Publishing dates

    Step 1: Confirm Status is Published (Note is not Status)

    System → Site Modules. Filter carefully. Administrator modules are a different list (Administrator Modules). A login module you edited in the backend list will never appear on the site.

    Open the module you think is missing. Status must be Published. Unpublished and Trashed do not render. A yellow or grey icon in the list is easy to miss if you sorted by Note.

    The Note field (Administrator Note) is a private reminder in the module list. It does not publish anything. It does not unpublish anything. Operators scan the Note column, see a comment such as “hold” or “old,” and assume Joomla unpublished the row. Read the Status column, then the module header Status dropdown.

    Also check you are not editing a Save as Copy draft. Two rows, same title, one Published on Home, one Unpublished. The frontend uses the published id. Confirm the id in the URL (id=) matches the row you intend.

    If Status is Published and you still see nothing, do not toggle it twice “to refresh.” Leave it Published and continue.

    Step 2: Match Access to the visitor you are testing

    Access is a veto.

    • Public: guests can see it (if every other check passes).
    • Guest: logged-in users may not see it (depending on your ACL). Super Users testing while logged in will swear the module is missing.
    • Registered and above: guests will not see it. That is correct ACL, not a bug.

    Test a private window logged out if the module should be public. Test a registered account if it should be members-only. Do not debug Access while logged in as Super User unless you also check a guest.

    ACL background: Access Control List and the user manual Access Control.

    If the site is multilingual, Access still applies per request. Language is a separate veto (Step 4).

    Step 3: Rule out Menu Assignment of No pages

    Open Menu Assignment.

    If Module Assignment is No pages, the module never renders. That looks identical to Unpublished on the frontend. Set it to On all pages for this diagnosis, save, retest one URL. If it appears, Assignment was the veto. Then set the real map using module showing on the wrong pages. Do not rebuild that whole Itemid article here.

    If Assignment is Only on the pages selected and the tree has no ticks (or only a hidden-menu item you are not visiting), the module is effectively No pages. Expand: All. Confirm the item for the URL you have open is ticked.

    If Assignment is On all pages and the module is still missing everywhere, Assignment is not the problem. Continue. If it is missing on some URLs and present on others, you are on the wrong-pages article, not this one.

    Default for a new module is often On all pages. Copies inherit whatever the original had, including No pages from a test.

    Step 4: Set Language to All, or to the language of the page

    Language on the module must be All, or the same language as the page Joomla is serving.

    With System – Language Filter published, a module set to English is omitted on the French page even when Status is Published and Assignment includes that menu item. That is Language Filter doing its job.

    Test:

    1. Set Language to All. Save. Clear cache. Retest.
    2. If you need per-language modules, duplicate the module (Save as Copy), set each copy’s Language, and assign each to the matching menu items. Do not expect one English module to print on every language.

    Site vs Administrator language packs do not apply here. This is the module’s Language field on Site Modules.

    Step 5: Check Start Publishing and Finish Publishing

    Open the Publishing tab.

    • Start Publishing in the future: Status can say Published. The module still waits. Site timezone is Global Configuration, not your laptop clock.
    • Finish Publishing in the past: the module has expired. Published-looking rows still vanish.
    • Empty dates: no date veto.

    A campaign module you scheduled last quarter will “randomly” disappear on the Finish day. That is not cache and not a template update.

    If you use scheduled tasks or a workflow elsewhere, they do not replace these two fields. Read the Publishing tab on the module itself.

    Step 6: Clear module cache and Page Cache after a real fix

    Once Status, Access, Assignment, Language, and dates are correct, an empty guest page can still be yesterday.

    1. System → Maintenance → Clear Cache. If that does nothing, the handler may be Redis: Joomla cache not clearing.
    2. Module Advanced → Caching. A cached empty output can survive your publish click until the cache key expires. Set to No caching on staging to prove it, then put a sane cache back.
    3. System – Page Cache: guests get a full HTML snapshot from before the module was published. Logged-in Super Users skip it and think the site is fine. Test a private window. Layers: cache showing old content.

    Progressive System Cache is aggressive about module combinations. If a module “won’t come back” after you publish it, Progressive plus Page Cache is a usual pair. Conservative is enough for most sites.

    Do not “fix cache” by deleting cache/ in FTP when Cache Handler is Redis.

    Step 7: Only then ask whether the position exists

    If every check above passes and View Source still has no module HTML on a page that should include it:

    • The position string may not exist on this template (position-7 on Cassiopeia, or a name with no jdoc). That is module position not showing.
    • The menu item may use a different template style whose index.php never includes that position. Still a position/style problem, not Status.

    If View Source has the module HTML, the module showed. Chrome, CSS, or a script hid it. CSS: Joomla CSS changes not showing. JS emptying the node: Joomla JavaScript not working.

    Do not add a jdoc to parent Cassiopeia to “make it show.” Extra positions belong on a child template. Safe file rule: customize without editing core.

    Custom HTML inside the module that looks stock is an override or chrome issue, not unpublished: template override not working.

    Five checks: published, access, assignment and language, cache, dates and note

    Status, then Access, then Assignment plus Language, then cache, then dates. Treat Note as a label, not a switch. Position wiring is a later article.

    Key takeaways

    1. A Joomla module is not showing when a veto failed: Status, Access, Language, Menu Assignment, dates, or cache. Note is not a veto.
    2. Test as a guest in a private window. Super User Access proves little for Public modules.
    3. No pages (or Only-on-selected with no ticks) looks like Unpublished on the frontend.
    4. Language Filter hides modules whose Language is not All and not this page’s language.
    5. Start Publishing in the future and Finish Publishing in the past hide a Published row.
    6. Page Cache and module cache keep an empty guest page after you fix the row.
    7. Position name vs jdoc is module position not showing. Wrong URLs are wrong pages.
    8. Do not edit core index.php to compensate for Unpublished.

    Frequently asked questions

    Why is my Joomla module not showing?

    Status is not Published, Access or Language excludes the visitor, Menu Assignment is No pages or unticked, Start or Finish dates hide it, or cache still has the empty page. Check those before you touch the template.

    What is the difference between a Note and Unpublished?

    Note is an administrator reminder in the module list. Unpublished is Status. Only Status (and dates, Access, Language, Assignment) control the frontend.

    Should I fix the template position first?

    Only after this list passes. If the module is unpublished, a perfect jdoc still prints nothing. Position wiring is Joomla module position not showing.

    Why do I see the module when logged in but guests do not?

    Access is not Public, or Page Cache is serving guests an old empty HTML page. Test a private window after Clear Cache.

    Can Language hide a published module?

    Yes. With Language Filter on, a module set to one content language is omitted on the other. Set Language to All to prove it.

    The module shows on Home but not on Contact. Is that this guide?

    That is Menu Assignment / Itemid. Use Joomla module showing on the wrong pages. This page is for modules that show nowhere (or nowhere for that visitor).

    Where are the official module assignment docs?

    How do you assign a module to specific pages? and Module display by menu item.

    Conclusion

    When a Joomla module is not showing, read the module row like an operator: Published, Public (or the Access you intend), Assignment that is not No pages, Language All or matching, dates that include now, then cache. Ignore the Note column as a status. If that list is clean and the slot is still empty, the position name or the template style is next: module position not showing. If the module is visible on the wrong URLs, that is wrong pages.

    If production has copies, languages, and Page Cache stacked, Joomla support and maintenance is faster than toggling Status. Layout and chrome work: Joomla design services.

  • How to Update Joomla and Fix Update Errors

    How to Update Joomla and Fix Update Errors

    Updating Joomla to the latest version means applying the official update package through System → Update → Joomla (older sites: Components → Joomla Update). A Joomla update error is almost always one of four failures: the update server cannot be reached, PHP runs out of memory or time while downloading the ZIP, files cannot be extracted because of permissions, or the database schema is left behind after files change. Major jumps (3 to 4, 4 to 5, 5 to 6) are upgrades, not one-click patches, and need a staging plan.

    This is the Infyways runbook for Joomla 4, 5, and 6. It covers the clean update path, every common error, the manual Upload & Update fallback, and when to stop and hire a migration instead of forcing Live Update.

    What you will learn

    • How to update Joomla to the latest version inside the same major (5.4.x to 5.4.y, or 6.1.x to 6.1.y)
    • Why a next major does not appear until you switch the update channel
    • How to read administrator/logs/joomla_update.php so you stop guessing
    • Fixes for download failures, out of memory, timeouts, extract errors, and database schema lag
    • The Upload & Update method when the host blocks outbound HTTPS

    Update vs upgrade: do not mix them

    A Joomla update stays inside one major version. Example: 5.4.2 to 5.4.3, or 6.1.1 to 6.1.2. The built-in updater is the right tool.

    A Joomla upgrade changes the major number: 3 to 4, 4 to 5, or 5 to 6. Extensions, PHP, and templates can break. Do that on a staging copy with a tested backup. Our Joomla upgrade service is for that job. This article is for the updater itself and the errors it throws.

    Goal Update channel Where
    Latest patch of your current major Default System → Update → Joomla
    Next major (for example 5.4 to 6) Joomla Next Same screen, Options, then Pre-Update Check
    Updater cannot download the ZIP Either Download the official update package and use Upload & Update
    Joomla 3 or heavily customized site Do not force one click Staged migration. See Joomla 3 to 6 path

    Official references: Updating from an existing version and Joomla Update problems.

    Step 1: Confirm the installed version and the target

    1. Log into the administrator.
    2. Open System → Update → Joomla. If that menu is missing, see the FAQ below (rebuild menus, or look under Components on very old builds).
    3. Note the installed version and the version Joomla offers.
    4. Open System → System Information and record PHP version, database type, and memory limit.

    If the offered version is only a patch and Pre-Update Check is green, continue. If you expected Joomla 6 and only see 5.4.x, you are still on the Default channel. That is not a bug.

    Step 2: Back up files and the database

    Do not click Start Update on a production site without a restorable backup. Use Akeeba or a host snapshot, then keep one copy off the server. Full method: How to backup a Joomla website.

    If the update dies halfway, restore first. Debugging a half-written core is slower than a clean restore.

    Step 3: Check the server before the download

    • PHP memory: sites have failed updates at 96 MB and succeeded at 192 MB. Set memory_limit to at least 256M before a core update.
    • Time: raise max_execution_time (120 seconds or more). Shared hosts also kill long PHP-FPM requests.
    • Upload limits (needed for the manual ZIP path): upload_max_filesize and post_max_size above the package size (often 20 to 40 MB, sometimes larger).
    • Writable paths: tmp/, administrator/logs/, and the site root must be writable by PHP.
    • Outbound HTTPS: the server must reach https://update.joomla.org (and historically GitHub CDNs used by the update infrastructure). Firewalls that block outbound HTTPS cause “failed to download” with a healthy admin.
    • Disk space: leave room for the ZIP plus extracted files. A full disk looks like a random extract error.

    Step 4: Set the update channel

    1. On the Joomla Update screen, open Options.
    2. For a normal latest-version update, keep Update Channel on Default.
    3. Only switch to Joomla Next when you intentionally want the next major, and only after staging, PHP, and extension checks.
    4. Save & Close, then reload the update screen.

    Joomla 6 will not appear from Joomla 5.4 until the channel is Joomla Next and the server meets Joomla 6 requirements (current PHP 8.3-class, supported MySQL/MariaDB or PostgreSQL). The Behaviour – Backward Compatibility plugin rules also block that hop if they are wrong. Read Behaviour – Backward Compatibility before a 5.4 to 6 upgrade.

    Step 5: Run Pre-Update Check, then start the update

    1. Read Required settings, Recommended settings, and Extensions.
    2. Update or disable extensions that the check flags as incompatible. The check is metadata, not a full runtime test, so still keep the backup.
    3. Confirm you have a backup.
    4. Click Start Update (wording varies slightly by version) and leave the tab open until it finishes.
    5. After success, open System → Maintenance → Database, select Joomla CMS, and click Update Structure / Fix if any tables are listed.
    6. Clear Joomla cache and your host cache. Test the homepage, login, and one form.

    Error map: match the symptom to the fix

    What you see Usual cause Fix
    No update offered, or only an old patch Wrong channel, or update server unreachable Options → Default or Joomla Next. Then check outbound HTTPS
    Failed to download update package / could not connect Firewall, DNS, TLS, or update.joomla.org blocked Read the log. Ask the host to allow outbound HTTPS. Use Upload & Update
    Out of memory, or download dies with no clear reason memory_limit too low (96 MB is a known failure point) Raise to 256M and retry. Confirm in System Information
    Progress bar stalls, then a timeout or blank page PHP or proxy timeout during a large ZIP Raise execution time, retry off-peak, or upload the package manually
    Extract failed / could not create file Permissions, open_basedir, or full disk Fix ownership on tmp and core folders. Free disk. Retry
    Files updated, admin shows database errors SQL schema step did not finish System → Maintenance → Database → Fix
    White screen or 500 right after update PHP version, incompatible extension, or .htaccess Error log first. See mod_rewrite 500 and extension disable via database if locked out
    Class JRequest not found after a major hop Legacy extension code Replace JRequest with getInput()
    Joomla 6 button missing on 5.4 Channel still Default, or PHP too old, or compat plugin mis-set Joomla Next + PHP check + compat plugin guide

    Step 6: Read the update log before you change ten settings

    Open administrator/logs/joomla_update.php (or download it from the host file manager). Look at the last lines around the failure time.

    • Attempting to download then nothing: connectivity, timeout, or memory during download.
    • Download failed with a URL on update.joomla.org: outbound HTTPS or TLS.
    • Error extracting: permissions or disk.
    • Finalizing / cleanup then a PHP fatal on the next page: the core files may already be new. Fix the extension or PHP error. Do not start a second update on top.

    Step 7: Upload & Update when download keeps failing

    1. On a computer that can reach the internet, download the Update Package ZIP for your exact target from the official Joomla downloads (not a random mirror). Use the update package, not the full install package with an installation/ folder, unless you are doing a manual file replace and know the extra steps.
    2. In the administrator open Joomla Update and choose Upload & Update (or the package upload tab).
    3. Upload the ZIP and run the installer.
    4. If upload fails immediately, raise upload_max_filesize and post_max_size, then retry.
    5. Finish with Database Fix and a cache clear.

    This bypasses the server’s outbound download. It does not bypass PHP memory during extract, so still raise memory_limit.

    Step 8: If the administrator will not load after the update

    1. Read the PHP / host error log. The class or file named there is the clue.
    2. If it is a third-party extension, rename that extension’s folder via FTP (or set enabled = 0 in #__extensions) so Joomla can boot.
    3. If it is .htaccess / mod_rewrite, rename .htaccess temporarily and follow the 500 on mod_rewrite guide.
    4. If the database is mid-schema, restore the backup rather than clicking update again.

    Step 9: After a successful update

    • Confirm the version in System Information matches the package you intended.
    • Update extensions from System → Update → Extensions.
    • Re-enable anything you disabled for the check.
    • Submit the sitemap if URLs changed (they should not on a patch update).
    • Watch the site for a day. Keep the pre-update backup until you are sure.

    When one-click update is the wrong tool

    Stop and plan a migration if any of these are true:

    • You are on Joomla 3 (or older) and want Joomla 5 or 6
    • Pre-Update Check lists many incompatible extensions you cannot replace yourself
    • The template is a heavily overridden club template with no vendor update
    • VirtueMart, K2, or custom components are business-critical
    • Two update attempts already failed and the log is unclear

    Infyways runs those as staged upgrades from $149, with a free compatibility audit. Start at Joomla Upgrade Services or contact us.

    Key takeaways

    1. Same-major updates belong in System → Update → Joomla on the Default channel.
    2. Next majors need the Joomla Next channel, current PHP, and a staging backup.
    3. Read joomla_update.php before changing random PHP settings.
    4. Raise memory to at least 256M. 96 MB is a known way to fail the download.
    5. If outbound HTTPS is blocked, Upload & Update with the official update ZIP.
    6. Always run Database Fix after the files change.

    Frequently asked questions

    How do I update Joomla to the latest version?

    Back up the site, open System → Update → Joomla, keep the Default channel for a patch, pass Pre-Update Check, then Start Update. Finish with System → Maintenance → Database if needed.

    Why is the Joomla Update menu missing?

    On current Joomla it lives under System → Update → Joomla, not always under Components. If the whole administrator menu is broken, rebuild menus from a working backup or ask your host to confirm the admin template is intact.

    Why does Joomla say there is no update when I know a new version exists?

    You may be on the wrong channel, or the server cannot reach update.joomla.org. Check Options, then the update log.

    How do I fix “failed to download the update package”?

    Allow outbound HTTPS to update.joomla.org, raise PHP memory and execution time, then retry. If the host still blocks downloads, use Upload & Update with the official ZIP.

    The update finished but the site shows database errors. What now?

    Go to System → Maintenance → Database, select the Joomla CMS item, and run the structure fix. Do not restore unless that fix fails.

    Can I update Joomla 3 to Joomla 6 from this screen?

    No. That is a multi-hop upgrade (3.10 to 4.4 to 5.4 to 6), not a single updater click. Use a staged plan.

    Is it safe to update on the live site?

    Patch updates are usually safe after a backup. Major upgrades should be proven on staging first.

    Who can fix a stuck Joomla update for me?

    Infyways handles failed updates and full version migrations. Request a Joomla upgrade audit.

  • How to Fix Common Joomla Upgrade Issues

    How to Fix Common Joomla Upgrade Issues

    Joomla upgrade issues are failures that show up when you change major version (3 to 4, 4 to 5, or 5 to 6), not ordinary patch updates. The usual causes are an extension or template still calling removed APIs, PHP or the database below the target version, a schema update that never finished, or a compatibility plugin left on the wrong setting. A blank page after the files copy is a PHP fatal. Fix the fatal. Do not click update again.

    This is the Infyways map for those breaks on Joomla 4, 5, and 6. If the updater itself cannot download the ZIP, that is a different problem: use how to update Joomla and fix update errors.

    What you will learn

    • Which symptoms mean an extension, a template, PHP, the schema, or the compatibility plugin
    • The only safe hop order: 3.10 to 4.4, then 5.4, then 6
    • Current PHP and database floors for Joomla 5 and Joomla 6
    • How to get the administrator back when you are locked out
    • When to stop and run the jump on staging instead of the live site

    Issue map

    What you see Usual cause Fix
    White screen or 500 right after the upgrade PHP fatal in an extension, template, or .htaccess Read the host error log. Disable that extension. See the 500 guide if the log mentions rewrite
    Class “JRequest” or “JFactory” not found Joomla 3 API removed in Joomla 4+ Replace JRequest with getInput(). The compatibility plugin does not restore JRequest
    Unknown column, or table does not exist SQL schema step did not finish System → Maintenance → Database → Update Structure
    Next major never appears Update channel still Default, or PHP too old Joomla Next channel, then meet the PHP floor below
    Site looks unstyled or modules vanish Template or layout overrides built for Bootstrap 2 / Joomla 3 Switch to Cassiopeia to confirm, then update or replace the template
    Pre-Update Check blocks Joomla 6 Behaviour – Backward Compatibility plugin, or server below Joomla 6 Set the compatibility plugin, then fix PHP and the database
    Search or Weblinks menu errors Those components left the core in Joomla 4 Use Smart Search. Install a maintained replacement only if you still need the old feature
    Cart or catalog dies (VirtueMart, K2) Extension build does not match the new major Update that product to a build made for the target Joomla before go-live
    Login loop after upgrade Session table, cookie domain, or $live_site Empty #__session, confirm the site URL in Global Configuration
    Download failed, out of memory, stalled bar Updater transport, not compatibility Update-error runbook

    Do not skip versions

    You are on Get current first Next hop Not this
    Joomla 3.9 or older 3.10.x Joomla 4.4 A direct jump to 5 or 6
    Joomla 3.10 Extensions that have a Joomla 4 build 4.4 on staging One-click on production
    Joomla 4.0 to 4.3 4.4.x Joomla 5 Joomla 6
    Joomla 5.0 to 5.3 5.4.x Joomla 6 only from 5.4 Skipping 5.4
    Joomla 5.4 PHP 8.3+, supported database, compat plugin Joomla 6 Ignoring Pre-Update Check

    Joomla 3 reached end of life in August 2023. Planning notes from the project: Joomla 3 to 4 step-by-step migration. Our path write-up: Joomla 3 to 4, 5, and 6.

    Server floors that cause upgrade issues

    The 2023 requirements table (PHP 7.2, MySQL 5.6) is obsolete. Use the current manual: Joomla technical requirements.

    Target PHP Database you should be on
    Joomla 5 8.1 or newer. Prefer 8.2 or 8.3 MySQL 8.0.13+ or a current MariaDB. PostgreSQL 12+ if you use it
    Joomla 6 8.3.0 minimum. 8.4 recommended MySQL 8.0.13+ (8.4 recommended), MariaDB 10.6+ supported (10.4 is only the absolute floor), PostgreSQL 14+ supported

    Joomla 6 also expects the PHP modules json, simplexml, dom, zlib, gd, and a database driver (mysqlnd, pdo_mysql, or pdo_pgsql). Recommended memory is at least 256M. Raise that before the upgrade, not after a fatal.

    Step 1: Name the version hop

    1. In the administrator, open System → System Information and note Joomla, PHP, and the database version.
    2. Decide the single next hop from the table above. Do not chain 3 to 6 in one afternoon on the live site.
    3. Take a restorable backup first. Method: how to backup a Joomla website.
    4. Run that hop on a staging copy. Promote it only after the homepage, login, one form, and checkout (if any) work.

    Step 2: Capture the real error

    1. Turn on Joomla debug only on staging: Global Configuration → System → Debug System, and set Error Reporting to Maximum.
    2. On production, leave display_errors off. Read the host PHP log and administrator/logs/.
    3. Copy the first fatal line: class name, file path, and line number. Later fatals are often fallout.
    4. If the log names .htaccess or mod_rewrite, stop and follow Joomla 500 on mod_rewrite.

    Step 3: Fix PHP and the database before retrying

    If System Information shows PHP below the floor for your target, the upgrade will fail or boot into fatals. Ask the host to switch PHP, then retest extensions on that PHP version before you change Joomla. A site that runs on PHP 8.0 cannot move to Joomla 6 until PHP is 8.3 or newer.

    Same for MySQL 5.7 or a very old MariaDB. Move the database into the supported range, confirm utf8mb4, then upgrade Joomla.

    Step 4: Repair the schema

    1. If you can still open the administrator, go to System → Maintenance → Database.
    2. Select the Joomla CMS entry (and any extension that shows problems).
    3. Click Update Structure.
    4. Reload the site. If the error was “unknown column” or “table doesn’t exist” and it is gone, you are done with this class of issue.

    If the administrator will not load, restore the backup. Do not keep launching the updater on a half-migrated schema.

    Step 5: Disable the extension that crashed

    When the log names a file under /plugins/, /modules/, /components/, or /templates/ that is not Joomla core:

    1. Prefer the administrator: System → Manage → Extensions, disable that extension, clear cache.
    2. If you cannot log in, rename that extension folder over FTP or SFTP so Joomla stops loading it.
    3. Or set enabled = 0 for that row in #__extensions. Match element and folder, not a guess.
    4. Install a build made for the new major, or replace the extension. Re-enable only after that.

    Pre-Update Check is metadata. It will not execute every code path. An extension can be listed as compatible and still fatal on your overrides.

    Step 6: Repair the template and layout overrides

    Joomla 4 replaced Bootstrap 2 and MooTools with Bootstrap 5 and Web Asset Manager. A Joomla 3 template, or a templates/YOUR_TEMPLATE/html/ override copied forward, will break layout, module chrome, or the whole page.

    1. Set the site template to Cassiopeia (System → Site Templates). If the site renders, the CMS is fine and the old template is the issue.
    2. Update the commercial template (Helix, T4, Gantry, and similar) to a release built for your Joomla major.
    3. Diff layout overrides against the new core layouts. Old overrides that call removed classes need a rewrite, not a file copy.
    4. Put the real template back only after a full click-through.

    Step 7: Restore SEF without taking the site down

    A major upgrade often rewrites .htaccess or leaves “Use URL Rewriting” on while the server still rejects Options or RewriteRule. Symptom: homepage maybe works, every other URL is a 500 or a 404.

    • Rename .htaccess to htaccess.bak so the site boots.
    • Turn off Use URL Rewriting until the new file is valid.
    • Rebuild from htaccess.txt using the mod_rewrite guide.
    • Confirm redirects you added by hand (www, HTTPS, old menu aliases) still exist. A fresh .htaccess drops them.

    Step 8: Retest, then take the next hop

    • Homepage, login, one article, one contact or checkout, and the administrator.
    • System → Update → Extensions, so third-party code matches the new core.
    • Language packs. An English core with a stale translation can hide menu types.
    • Clear Joomla cache and any host or CDN cache.
    • Keep the pre-upgrade backup until the next business day.
    • Only then plan the following major, on staging again.

    Removed APIs and the compatibility plugin

    Joomla 4 deleted the Joomla 3 class layer: JRequest, JFactory, JError, and a long list of J* helpers. The System – Backward Compatibility plugin brings some of that back. It does not bring JRequest back. Code that still calls JRequest::getVar() must move to Factory::getApplication()->getInput().

    The 5.4 to 6 hop adds another gate: Behaviour – Backward Compatibility. If that plugin is disabled or set to the wrong mode, Pre-Update Check blocks Joomla 6 even when PHP is fine. Settings and the safe order are in Behaviour – Backward Compatibility.

    VirtueMart, K2, and page builders

    These fail more often than core articles:

    • VirtueMart: install the VirtueMart build that declares your target Joomla major before you switch the core. A Joomla 3 cart on Joomla 5 will fatal in the shop, not in the updater.
    • K2: treat it as a migration. Many K2 sites need a content move, not an in-place upgrade.
    • Helix, SP Page Builder, Quix, Gantry: update the builder to the vendor release for that Joomla version, on staging, before the core hop.

    When to stop clicking Update

    Hire a staged upgrade if any of these are true:

    • You are still on Joomla 3 and the business cannot sit on a broken staging copy
    • Pre-Update Check lists extensions you cannot replace
    • Two attempts already left the schema or the administrator broken
    • Checkout, memberships, or a custom component is the revenue path

    Infyways runs those jumps from $149, with a compatibility audit within 12 hours. Start at Joomla Upgrade Services.

    Key takeaways

    1. Upgrade issues are major-version breaks. Patch updates use the other guide.
    2. Hop order is 3.10, then 4.4, then 5.4, then 6. No shortcuts.
    3. Joomla 6 needs PHP 8.3 or newer. Joomla 5 needs PHP 8.1 or newer.
    4. Read the first fatal. Disable that extension. Then fix schema, template, and .htaccess.
    5. The compatibility plugin does not fix JRequest.
    6. Prove the hop on staging. Keep the backup until the live site has been quiet for a day.

    Frequently asked questions

    What are the most common Joomla upgrade issues?

    Incompatible extensions, old templates and layout overrides, PHP or database versions below the target, an unfinished database schema, and a mis-set compatibility plugin on the way to Joomla 6.

    Why is my site blank after a Joomla upgrade?

    A PHP fatal is hiding the page. Read the host error log, disable the extension or template named there, and do not run the updater again until the administrator loads.

    Can I upgrade from Joomla 3 directly to Joomla 6?

    No. Move 3.10 to 4.4, then to 5.4, then to 6, each hop tested on staging.

    What PHP version do I need?

    Joomla 5 needs PHP 8.1 or newer. Joomla 6 needs PHP 8.3.0 or newer, with 8.4 recommended. Details are in the Joomla technical requirements.

    How do I fix database errors after upgrading?

    Open System → Maintenance → Database and run Update Structure. If the administrator will not load, restore the backup instead of launching another update.

    Why do extensions break when Joomla itself updated cleanly?

    Core files can be new while an extension still calls Joomla 3 classes or old layouts. Update or replace that extension, or disable it until a compatible build exists.

    Does the backward compatibility plugin fix every old extension?

    No. It covers a limited set of legacy calls. It does not restore JRequest, and Joomla 6 will not start the upgrade until Behaviour – Backward Compatibility is configured.

    Is it safe to upgrade the live site?

    Patch updates are usually safe after a backup. Major upgrades should be proven on staging first.

    Who can fix a broken Joomla upgrade?

    Infyways handles failed upgrades and full version jumps. Request a Joomla upgrade audit.

  • How to Remove MooTools from Joomla

    How to Remove MooTools from Joomla

    MooTools is a JavaScript framework Joomla used from 1.5 through 3.10 for SqueezeBox popups, image captions, and older effects. Joomla 4, Joomla 5, and Joomla 6 do not ship it. Core in those versions uses the Web Asset Manager, Bootstrap 5, and media/system/js/core.js. If a current site still requests mootools-core.js, a template or extension is loading its own copy.

    People remove it to cut unused JavaScript and to stop fights with jQuery over the $ symbol. On Joomla 3 that is safe only after you replace captions and modals. Deleting every script tag, which is what a lot of old snippets do, takes jQuery and the template down with it.

    What you will learn

    • What MooTools was for, in general and inside Joomla
    • Which versions still include it, and which do not
    • Why caption.js keeps showing up on ordinary article pages
    • Why speed plugins and developers want it gone
    • How to remove only those files on Joomla 3, and what to do when Joomla 4+ still loads them

    What MooTools is

    MooTools is an open-source JavaScript library, not a Joomla extension. It gave developers a class system, DOM helpers, events, animation (Fx), and Ajax (Request). The copy Joomla 3 shipped is MooTools Core 1.4.5, plus MooTools More 1.4.0.1 when something asked for the extra effects. Official inventory: Joomla 3 JavaScript frameworks.

    The MooTools project itself stalled. Its last release line is 1.6.0 from 2016, and Joomla never moved the CMS copy up to that. You are looking at an unmaintained library frozen inside Joomla 3.

    It is not jQuery. Joomla 3 shipped both. jQuery is a separate, optional asset even on Joomla 4 and 5 (jquery in the Web Asset Manager). Removing MooTools does not remove jQuery, and you should not treat them as the same cleanup.

    What Joomla used it for

    Joomla did not load MooTools on every page by itself. A layout, template, or extension called a behavior, and that behavior added the files. These are the calls that mattered:

    Call Files it pulled What you saw on the site
    JHtml::_('behavior.framework') mootools-core.js. Pass true and it also loads mootools-more.js Nothing visible. Later scripts then use $, $$(), and window.addEvent('domready')
    JHtml::_('behavior.caption') Core plus caption.js Images with class caption get a text line under them, read from the title
    JHtml::_('behavior.modal') Core plus modal.js and modal.css SqueezeBox. Links with class modal open in a lightbox
    Template or extension addScript Whatever path they hardcoded Sliders, accordions, menus, galleries written against MooTools

    Two details explain the script tags people paste into forum posts.

    • caption.js is why MooTools appears on plain articles. Joomla 3 article and blog layouts call behavior.caption. That loads MooTools even when the page has no popup and no slideshow. Since Joomla 3.2.2 the editor inserts real figure and figcaption tags, but the old script stayed so articles written before that still got captions.
    • The file is not named mootools.js on Joomla 3. Core ships /media/system/js/mootools-core.js and /media/system/js/mootools-more.js. The single mootools.js name is the Joomla 1.5 file, or a template that copied it. Search for mootools, not one exact filename.

    Older Joomla also used MooTools for tooltips and form checks. By 3.10 most of those had moved to Bootstrap and jQuery. Modals and captions did not. SqueezeBox was still the modal implementation in 3.10. There is a long core discussion of that leftover: MooTools is still required by modals.

    Which versions include it

    Joomla MooTools in core? What to do
    1.5 Yes. It was the JavaScript framework Upgrade. Do not spend time micro-optimizing 1.5
    1.6, 1.7, 2.5 Yes Same. These releases are long out of support
    3.0 to 3.10 Yes, deprecated. Core 1.4.5 and More 1.4.0.1. Loaded only when a behavior or extension asks Remove the caller on the frontend after you replace captions and modals. Leave the files on disk
    4.0 and later No. Removed from core, along with caption.js and SqueezeBox If the file still loads, it is third-party. Update or replace that extension
    5.x and 6.x No Same as Joomla 4. Core scripts are core.js and Bootstrap, not MooTools

    Joomla 4’s own break list says caption.js is gone and captions must be figure and figcaption: Potential backward compatibility issues in Joomla 4. Joomla 5 and 6 inherited that. They did not put MooTools back.

    A compatibility plugin does not restore it either. Behaviour – Backward Compatibility covers selected PHP APIs. It does not inject mootools-core.js.

    Why people want it removed

    • Unused weight. On a Joomla 3 article page the caption behavior adds render-blocking scripts in the head. If you have no img.caption and no SqueezeBox link, the browser still downloads and parses them.
    • The $ clash. MooTools claims $. Joomla loads jQuery and then jquery-noconflict.js, which gives $ back. Whichever library runs last owns $. A template script that expects jQuery throws “is not a function”. A MooTools slider dies the other way. Removing the library you do not need is one fix. Wrapping jQuery as jQuery(function ($) { ... }) is the other, and it is safer when something still needs MooTools.
    • No upstream fixes. A 2016-era library inside a CMS that stopped at 3.10 will never get a modern browser pass or a security release of its own.
    • PageSpeed. Lighthouse flags it as unused JavaScript. The win is real only when the page still works afterward. A broken menu costs more than a few kilobytes.
    • Stack conflicts. Bootstrap, Vue, Alpine, and current templates were not written against MooTools 1.4. Old effects CSS also collides with SqueezeBox’s modal.css.
    • Migration. Joomla 4 deletes the files. A Joomla 3 site that still needs them is carrying a blocker into the upgrade. Fix the dependency before the hop, not during a failed update. Path and breakage notes: Joomla upgrade issues and Joomla 3 to 4, 5, and 6.

    What breaks if you strip it blindly

    • Captions on old articles that use <img class="caption"> instead of figcaption
    • Any class="modal" link that expected SqueezeBox
    • Template features written with Fx.Slide, Fx.Accordion, or Tips
    • Extensions that still call behavior.framework: older galleries, some menu systems, some editors’ lightbox buttons
    • The administrator, if your snippet runs there too. Joomla 3 admin modals used SqueezeBox. Never strip MooTools from /administrator
    • Inline scripts that still say SqueezeBox.initialize. The file is gone, the inline code remains, and the console fills with errors

    Do not delete media/system/js/mootools-core.js from disk on Joomla 3. Core and extensions still print that URL. You get a 404, not a faster site. Stop the request. Leave the file.

    Step 1: Confirm the Joomla version

    1. Open System → System Information, or look at the footer of the administrator.
    2. If the version is 4, 5, or 6, skip the Joomla 3 unset snippet. Core is already clean. Go to Step 3 and find the third-party file.
    3. If the version is 3.10 or older, keep reading. Take a backup before you edit the template. Method: how to backup a Joomla website.

    Step 2: See the real script URL

    1. Turn off any “combine JS” or cache plugin first. Combiners hide mootools-core.js inside one bundled file, so view-source lies.
    2. Open a frontend article, view source, and search for mootools and caption.js.
    3. In the browser Network panel, filter by mootools. The Initiator column names the document or script that requested it.
    4. Note the path.
      • /media/system/js/mootools-core.js means Joomla 3 core, pulled in by a behavior.
      • /templates/yourtemplate/js/... or /media/com_something/ means that template or extension bundles its own copy. Common on Joomla 4+ leftovers.

    Step 3: Find the caller

    Search the site files (template, then components, modules, plugins, templates) for:

    • behavior.framework
    • behavior.mootools
    • behavior.caption
    • behavior.modal
    • mootools
    • SqueezeBox

    On Joomla 3, a hit inside components/com_content is core calling captions. That one is expected. Hits inside your template and third-party extensions are the ones you can turn off. On Joomla 4+, any hit is third-party. Update that extension, disable it, or replace it. There is no core switch labeled “MooTools”.

    Step 4: Replace captions and modals first

    1. For images, use figure and figcaption. The Joomla editor has done this since 3.2.2. Re-save old articles, or run a content replace from img.caption to that markup. After the move, caption.js has nothing to do.
    2. For popups, stop using class="modal" plus a rel attribute. That syntax is SqueezeBox. Use a Bootstrap modal, or on Joomla 4+ the core dialog pattern. behavior.modal does not exist on Joomla 4.
    3. Click every slider, tab, and gallery on a staging copy. If one of them dies with $ is not a function or Fx is not defined, that feature still needs the library. Update the extension before you block the file.

    Step 5: Unset only MooTools on the Joomla 3 frontend

    The reliable hook is onBeforeCompileHead in a system plugin. It runs after extensions have added scripts and before the head is printed. Code at the top of index.php runs too early, and the usual copy-paste deletes every script, not just MooTools. That broken pattern is called out in the next section.

    This version touches MooTools and caption.js only, and it leaves the administrator alone:

    <?php
    public function onBeforeCompileHead()
    {
        $app = JFactory::getApplication();
        if (!$app->isSite()) {
            return;
        }
    
        $doc = JFactory::getDocument();
        $head = $doc->getHeadData();
        if (empty($head['scripts']) || !is_array($head['scripts'])) {
            return;
        }
    
        foreach ($head['scripts'] as $url => $attrs) {
            $path = strtolower($url);
            if (strpos($path, 'mootools') !== false || strpos($path, 'caption.js') !== false) {
                unset($head['scripts'][$url]);
            }
        }
    
        $doc->setHeadData($head);
    }
    ?>

    Clear Joomla cache and the combiner cache, then view source again. mootools-core.js and caption.js should be gone. jQuery, your template file, and analytics should still be there.

    If the console says SqueezeBox is not defined, a layout is still calling behavior.modal. Remove that call. Unsetting the file does not remove the inline startup script.

    Step 6: Test the pages that used to need it

    • An article with an image caption
    • A page that used a lightbox or class="modal"
    • The menu, the slider, and the contact form
    • One login
    • The administrator home screen, media manager, and a modal field such as the article image picker

    Check the administrator even if the plugin returns early on admin. A template edit often runs on both sides.

    Step 7: On Joomla 4, 5, or 6, update the extension

    There is no core file to unset. Use the path from Step 2.

    • Template path: switch to Cassiopeia. If MooTools disappears, the template was loading it. Update the template or drop that script include.
    • Extension path: update it to a build made for your major, or disable it. Packing MooTools in 2026 means the vendor has not moved that feature to Joomla.request, Bootstrap, or plain JavaScript.
    • Do not add the Joomla 3 unset plugin to Joomla 4 and expect it to see Web Asset Manager scripts the same way. Assets registered with $wa->useScript() are not always sitting in the old scripts array. Disable the asset or remove the include at the source.

    The snippet that removes every script

    This is the code still circulating, including on older copies of this article. Do not use it:

    foreach ($headerstuff['scripts'] as $key => $value) {
        unset($headerstuff['scripts'][$key]);
    }

    The loop has no filter. It drops jQuery, template JavaScript, captchas, and statistics, then the site feels “lighter” because half of it no longer runs. Filter on mootools and caption.js, or do not ship the change.

    What to use instead

    Old MooTools piece Replacement
    behavior.caption and caption.js figure and figcaption
    behavior.modal and SqueezeBox Bootstrap modal, or the Joomla 4+ dialog field
    window.addEvent('domready', ...) document.addEventListener('DOMContentLoaded', ...) or a defer script
    $$('.item') document.querySelectorAll('.item')
    Request.HTML fetch, or Joomla.request() from core.js on Joomla 4+
    Fx.Slide / accordion CSS, or Bootstrap collapse
    $ as MooTools Keep jQuery behind jQuery(function ($) { }) if a script still needs jQuery

    Web Asset Manager is the loader on current Joomla, not JHtml::_('behavior.framework'). A script that only needs Joomla’s helpers depends on core. Add jquery only when that file truly uses jQuery. Docs: Web Asset Manager.

    When removing it is the wrong project

    If the template, the shop, and two galleries all fatal without MooTools, you do not have a script-tag problem. You have a Joomla 3 stack. Stripping the library will not make that stack current. Plan the upgrade, replace the extensions on staging, then the file disappears because Joomla 4 does not ship it.

    Infyways runs those jumps from $149, with a compatibility audit within 12 hours. Start at Joomla Upgrade Services.

    Key takeaways

    1. MooTools powered SqueezeBox, caption.js, and older effects. It is not jQuery.
    2. Joomla 3.10 still ships Core 1.4.5. Joomla 4, 5, and 6 do not ship it at all.
    3. Article layouts load caption.js, which is why the file shows up on pages that look static.
    4. Unset only URLs that contain mootools or caption.js, on the frontend, after captions and modals have a replacement.
    5. Never delete the core file on Joomla 3, and never unset every script in the head.
    6. On a current site, update the template or extension that is still bundling the library.

    Frequently asked questions

    What is MooTools used for in Joomla?

    On Joomla 3 it opens SqueezeBox modals and builds captions for images that use the caption class. Older templates also use it for sliders and accordions. Joomla 4 and newer core do not use it.

    Does the latest Joomla still use MooTools?

    No. Joomla 4 removed it, and Joomla 5 and 6 did not bring it back. A request for mootools-core.js on those versions comes from a template or extension.

    Why do people remove MooTools?

    The usual reasons are unused JavaScript on article pages, conflicts with jQuery over $, and the fact that the library has had no real release since 2016. PageSpeed scores are a side effect, not the only reason.

    Why are mootools-core.js and caption.js on every article?

    Joomla 3 content layouts call JHtml::_('behavior.caption'). That behavior loads both files so old img.caption markup still gets a caption.

    Will my site break if I remove it?

    It breaks wherever a template or extension still calls SqueezeBox, caption.js, or MooTools effects. Test those pages. The administrator on Joomla 3 should keep the library.

    Should I delete mootools-core.js over FTP?

    No. On Joomla 3 that only creates a 404, because core still prints the URL. Stop the behavior or unset that URL. On Joomla 4+ the file is not part of core.

    Is MooTools the same as jQuery?

    No. Joomla 3 loaded both. jQuery remains an optional Web Asset Manager asset on current Joomla. MooTools does not.

    What replaces caption.js and SqueezeBox?

    Use figure and figcaption for captions. Use a Bootstrap modal, or the Joomla 4 dialog, instead of class="modal".

    Can someone remove it without breaking the template?

    Yes. That means finding the caller, replacing captions and lightboxes, then unsetting only those scripts. Request a Joomla upgrade audit if the template still depends on it.

  • Fix Class JRequest Not Found in Joomla 4, 5, and 6

    Fix Class JRequest Not Found in Joomla 4, 5, and 6

    Class ‘JRequest’ not found means your extension, template override, or custom PHP still calls the removed Joomla 1.x/2.x/3.x request helper. JRequest was deprecated for years and is gone in Joomla 4+. It is not restored by the Behaviour – Backward Compatibility plugins. Replace every call with the Joomla Input API: Factory::getApplication()->getInput() (or $this->input inside a core MVC controller).

    This is one of the most common fatals after a Joomla 3 to 4 upgrade, and it still appears on Joomla 5 and 6 when an old module, plugin, or child-template override was never updated. Official Input docs: Joomla Input.

    What you will learn

    • Why Joomla removed JRequest and why the compat plugin will not bring it back
    • Exact old → new code replacements for getVar, getInt, getCmd, and related helpers
    • How to find every remaining JRequest usage on the server
    • Controller, module, plugin, and template override patterns that stay valid on Joomla 6
    • How filters work so you do not silently break integers, HTML, or form arrays

    Why the error appears after upgrading

    On Joomla 3, JRequest::getVar('foo') still ran (with deprecation noise in newer 3.x). On Joomla 4, 5, and 6 the class file is not loaded. PHP throws a fatal error as soon as that line executes.

    Typical sources:

    • Custom components and modules written for Joomla 2.5 / 3
    • Abandoned third-party extensions
    • Template overrides copied from an old html/ folder
    • One-off scripts in the site root or a cli/ helper

    The Behaviour – Backward Compatibility plugins bridge selected later APIs. They do not reintroduce JRequest. See our Behaviour – Backward Compatibility guide for what those plugins actually restore.

    Old JRequest call Modern replacement Notes
    JRequest::getVar('x') $input->get('x', null, 'STRING') or typed helper Default filter for get() is CMD, not “anything goes”
    JRequest::getInt('id') $input->getInt('id', 0) Always pass a default
    JRequest::getCmd('task') $input->getCmd('task', '') Safe for option/task style tokens
    JRequest::getBool('check') $input->getBool('check', false) Watch string "false" quirks; prefer real booleans
    JRequest::getWord('layout') $input->getWord('layout', '') Letters and underscore only
    JRequest::getFloat('price') $input->getFloat('price', 0.0) Or getDouble where available
    JRequest::getMethod() $input->getMethod() / server method checks Prefer framework request method helpers when available
    JRequest::setVar('x', $v) $input->set('x', $v) Use def() when you only want to set if missing

    Step 1: Capture the full stack trace

    Turn on error reporting on staging (or read administrator/logs/ and the PHP / server error log). The fatal line path tells you whether to edit an extension, a template override, or a custom file.

    Example message:

    Error: Class "JRequest" not found
    Calling: templates/YOUR_TEMPLATE/html/.../default.php:42

    Fix that file first. Searching the whole tree still matters because several files may call JRequest.

    Step 2: Find every JRequest usage

    From the site root (SSH) or a project-wide search in your IDE:

    grep -R --include="*.php" -n "JRequest" .
    # or
    rg -n "JRequest" -g "*.php"

    Also search case variants and legacy imports:

    rg -n "jrequest|JRequest::" -g "*.php" -i

    Skip libraries/ core and vendor trees unless you overwrote core (you should not). Focus on components/, modules/, plugins/, templates/, and any custom src/ folders.

    Step 3: Replace with Factory::getApplication()->getInput()

    Preferred modern form (Joomla 4, 5, and forward-compatible with Joomla 6 guidance):

    use Joomla\CMS\Factory;
    
    $input = Factory::getApplication()->getInput();
    $data  = $input->get('data', '', 'STRING');
    $id    = $input->getInt('id', 0);
    $task  = $input->getCmd('task', '');

    Avoid the older property access when you can:

    // Works on many CMS installs, but the public ->input property is deprecated for new code
    $input = Factory::getApplication()->input;

    Joomla’s migration notes recommend getInput() instead of reading the input property directly. See Joomla 5.4 → 6 deprecations.

    Old code

    $data = JRequest::getVar('data');
    $id   = JRequest::getInt('id');
    $view = JRequest::getCmd('view');

    New code

    use Joomla\CMS\Factory;
    
    $input = Factory::getApplication()->getInput();
    $data  = $input->get('data', null, 'STRING');
    $id    = $input->getInt('id', 0);
    $view  = $input->getCmd('view', '');

    Step 4: Use $this->input inside MVC controllers

    If your class extends Joomla\CMS\MVC\Controller\BaseController, Input is already available:

    $id   = $this->input->getInt('id', 0);
    $data = $this->input->post->get('jform', [], 'array');

    Do not call Factory::getApplication() again unless you are outside that controller context.

    Step 5: Match filters to the old intent

    Blindly changing getVar to $input->get('name') can break values because the default filter is CMD (strips many characters). Pick the filter that matches the old third argument or helper name.

    • INT / getInt for IDs and counts
    • CMD / getCmd for option, view, task, layout tokens
    • STRING / getString for normal text (HTML tags stripped)
    • HTML when you must keep markup more carefully (still sanitize before output)
    • ARRAY for jform style posts: $input->post->get('jform', [], 'array')
    • RAW only when you fully trust and validate afterward

    Typed helpers keep code readable:

    $name = $input->getString('name', '');
    $qty  = $input->getInt('quantity', 0);
    $ok   = $input->getBool('agree', false);

    Step 6: GET vs POST vs files

    Use nested input when the source matters:

    $getOnly  = $input->get->get('p1', 0, 'int');
    $postOnly = $input->post->get('p1', 0, 'int');
    $files    = $input->files->get('jform');

    On SEF sites, routing values like option and view come from the router as well as query strings. Prefer the main $input->getCmd('view') unless you intentionally need raw GET only.

    Step 7: Fix template overrides and modules

    Overrides under templates/TEMPLATE/html/ often keep decade-old snippets. After replacing JRequest:

    1. Clear Joomla cache
    2. Reload the exact menu item that crashed
    3. Re-run the project-wide search until zero hits remain in site-owned PHP

    For modules using a modern Dispatcher, inject Input (or read it from the application) instead of static JRequest calls. The official Input manual includes a full module sample.

    Step 8: Prefer updates over patches when the vendor still exists

    If the fatal sits inside a third-party extension:

    1. Install the vendor’s Joomla 4/5/6 native package
    2. Only then patch local forks if the product is abandoned
    3. Document every local patch so the next update does not overwrite your fix blindly

    A one-line site patch is fine for an override you own. It is a poor long-term plan inside administrator/components/com_oldthing/ that you did not write.

    Situation Best action
    Your custom module / override Replace with getInput() and commit the change
    Maintained commercial extension Upgrade to the Joomla 4+ package from the vendor
    Abandoned extension Patch if small, or replace the extension
    Only one leftover JRequest in a child template Fix the override; do not hack core

    Key takeaways

    1. JRequest does not exist on Joomla 4, 5, or 6. The fatal is expected until you remove the calls.
    2. Use Factory::getApplication()->getInput() or $this->input in MVC controllers.
    3. Map old helpers to typed getters and explicit filters. Default get() uses CMD.
    4. Search the whole site tree. One fixed file is not enough if overrides still call JRequest.
    5. Compatibility plugins will not resurrect JRequest. Update the code.

    Frequently asked questions

    What does Class ‘JRequest’ not found mean in Joomla 4?

    PHP tried to call the removed JRequest class. Update that code to the Input API before the page can load.

    Does this still happen on Joomla 5 and Joomla 6?

    Yes. Any leftover JRequest call fatals on current majors the same way.

    Will Behaviour – Backward Compatibility fix JRequest?

    No. Those plugins bridge other legacy pieces. JRequest must be replaced in code.

    Is JFactory::getApplication()->input still OK?

    It often still works, but new code should call getInput(). Prefer use Joomla\CMS\Factory over legacy JFactory aliases when you touch the file.

    Why did my value become empty after switching to input->get()?

    You probably hit the default CMD filter. Use STRING, INT, or another filter that matches the old getVar intent.

    How do I read jform POST data now?

    Use $input->post->get('jform', [], 'array'), then validate in the model the same way core components do.

    Can Infyways fix this on a client site?

    Yes. If you need a Joomla 3 to 4/5/6 upgrade with extension and override cleanup, contact Infyways.

  • Fix Joomla 500 Error on mod_rewrite

    Fix Joomla 500 Error on mod_rewrite

    A Joomla 500 error on mod_rewrite is almost always Apache rejecting a directive in your root .htaccess file right after you enable Search Engine Friendly URLs or “Use URL rewriting.” The browser only shows Internal Server Error. The Apache error log names the real cause: usually Options +FollowSymLinks, a missing AllowOverride, disabled mod_rewrite, or a bad RewriteBase.

    This guide is the fix path we use on Joomla 4, 5, and 6 sites (and older 3.x still on Apache). It complements our deeper Joomla .htaccess guide and the Joomla SEF URL setup.

    What you will learn

    • How to prove the 500 is caused by .htaccess / mod_rewrite in under two minutes
    • The exact Apache log messages that map to each fix
    • How to repair FollowSymLinks, AllowOverride, mod_rewrite, and RewriteBase
    • How to rebuild a clean Joomla .htaccess from htaccess.txt
    • What to check in Global Configuration and conflicting extensions

    Why Joomla shows 500 after enabling URL rewriting

    Joomla SEF without rewriting still works with index.php in the URL. Turning on Use URL rewriting tells Joomla to drop index.php and rely on Apache mod_rewrite plus the rules in .htaccess (renamed from the shipped htaccess.txt).

    If Apache cannot apply those rules, every front-end request can return HTTP 500. The administrator may still load if you open it with a direct /administrator/ path, which is a useful clue.

    Symptom / log clue Most likely cause First fix
    Site dies only after enabling URL rewriting .htaccess active and rejected Rename .htaccess to restore the site, then fix the directive
    Options not allowed here or FollowSymLinks error Host forbids Options in .htaccess Comment out Options +FollowSymLinks
    .htaccess ignored, URLs 404 AllowOverride None Set AllowOverride All (or FileInfo Options) in the vhost
    Invalid command RewriteEngine mod_rewrite not loaded Enable the module and restart Apache
    Works in root, breaks in subdirectory Wrong RewriteBase Set RewriteBase /subfolder/
    Works until a security extension ships custom rules Broken rewrite block from a plugin Disable the extension, restore core SEF section

    Step 1: Prove it is the .htaccess file

    1. Via FTP or file manager, rename root .htaccess to .htaccess.bak.
    2. Reload the homepage.
    3. If the 500 disappears (even if SEF URLs look ugly again), the rewrite file is the culprit.

    Do not leave rewriting enabled in Global Configuration while .htaccess is missing, or you will get 404s on pretty URLs. Temporarily turn Use URL rewriting off, then continue.

    Step 2: Read the Apache error log

    Guessing wastes time. Open today’s error log (cPanel “Errors”, Plesk logs, /var/log/apache2/error.log, or your host’s equivalent) and reload the site once.

    Look for lines that mention .htaccess, Options, RewriteEngine, or AllowOverride. Match them to the table above before editing Joomla again.

    Step 3: Fix Options +FollowSymLinks (the most common 500)

    Joomla’s shipped htaccess.txt includes Options +FollowSymLinks because mod_rewrite historically needed it. Many shared hosts already set symlink policy in the virtual host and forbid changing Options from .htaccess. Apache then returns 500 with “Options not allowed here.”

    In your .htaccess, comment the line:

    # Options +FollowSymLinks

    Some hosts prefer:

    Options +SymLinksIfOwnerMatch

    Official Joomla docs note that if commenting FollowSymLinks restores the site and SEF still works, your administrator already set the option server-side and you should leave it commented. See Preconfigured htaccess and Enabling SEF URLs.

    Step 4: Confirm AllowOverride permits .htaccess

    If you control the server (VPS, dedicated, local XAMPP/WAMP), open the virtual host or httpd.conf <Directory> block for the site document root and ensure overrides are allowed:

    <Directory "/var/www/html">
        AllowOverride All
        Require all granted
    </Directory>

    On shared hosting you usually cannot edit this. If AllowOverride is None, ask support to enable .htaccess overrides for Options and FileInfo, or to enable Joomla URL rewriting for your account.

    Restart Apache after config changes.

    Step 5: Enable mod_rewrite

    On Debian/Ubuntu:

    sudo a2enmod rewrite
    sudo systemctl restart apache2

    On RHEL/Alma/CloudLinux, ensure this line is uncommented in the Apache config and restart:

    LoadModule rewrite_module modules/mod_rewrite.so

    Quick PHP check on a throwaway file (delete after testing):

    <?php
    print_r(apache_get_modules());

    If mod_rewrite is missing from the list (or apache_get_modules is unavailable under PHP-FPM), confirm with your host. Without the module, leave Joomla URL rewriting off. SEF can still run with index.php in the path.

    Step 6: Rebuild .htaccess from htaccess.txt

    Corrupt or hand-edited rewrite blocks are a frequent source of 500s. Joomla ships a known-good template as htaccess.txt in the site root.

    1. Download a fresh copy from your Joomla version package if the root file is missing.
    2. Copy htaccess.txt to .htaccess (merge carefully if you already have custom redirects).
    3. Comment Options +FollowSymLinks if Step 3 applied.
    4. Keep core SEF rules inside the <IfModule mod_rewrite.c> block.

    Core SEF section (simplified shape; prefer the full file from your Joomla version):

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !^/index\.php
    RewriteCond %{REQUEST_URI} /component/|(/[^.]*|\.(php|html?|feed|pdf|vcf|raw))$ [NC]
    RewriteRule .* index.php [L]
    </IfModule>

    Never paste truncated snippets that smash the title or other text into the middle of a RewriteCond line. That alone will 500 the site.

    Step 7: Set RewriteBase for subdirectory installs

    If Joomla lives at https://example.com/shop/, set:

    RewriteBase /shop/

    Root installs usually use RewriteBase /. Wrong base values produce 500s or broken asset paths after rewriting is enabled.

    Step 8: Align Global Configuration

    In System → Global Configuration → Site (wording varies slightly by Joomla 4/5/6):

    • Search Engine Friendly URLs: Yes
    • Use URL rewriting: Yes only after .htaccess works
    • Adds Suffix to URL: optional
    • Unicode Aliases: as needed for non-ASCII

    Save, clear Joomla cache, then test a menu item URL. If enabling rewriting brings the 500 back, return to Steps 2 and 3. Keep SEF on and rewriting off until Apache is clean.

    Step 9: PHP-FPM Authorization line and host extras

    Some hosts need the HTTP Authorization pass-through for API or extension auth:

    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

    That line belongs in the core SEF section of a current Joomla .htaccess. Removing it rarely causes a 500, but a broken duplicate of it can. Also watch for host-injected blocks (LiteSpeed, Imunify, custom php_flag lines) that are invalid on your PHP handler. Comment suspect lines one at a time while watching the error log.

    Step 10: Rule out extensions and security plugins

    After the core file works, re-enable custom redirects and security rules carefully.

    • Disable recently installed SEF, security, or “firewall” extensions that write rewrite rules.
    • Check for a second .htaccess in /administrator or a subdomain docroot.
    • Restore from backup if a malware cleanup left garbage rewrite conditions.

    If the site was compromised, fix rewriting only after a clean restore. See our guide on repairing a hacked Joomla website.

    Nginx and IIS note

    mod_rewrite is an Apache module. Nginx uses try_files toward index.php. IIS uses web.config. A “mod_rewrite 500” on those stacks usually means you are reading Apache advice on the wrong server. Ask the host which web server fronts PHP before editing .htaccess.

    Key takeaways

    1. A Joomla 500 right after enabling URL rewriting is an Apache .htaccess problem until the error log proves otherwise.
    2. Commenting Options +FollowSymLinks fixes the majority of shared-hosting cases.
    3. Rename .htaccess to restore the site, then rebuild from htaccess.txt.
    4. Enable mod_rewrite and correct AllowOverride / RewriteBase before turning rewriting back on in Joomla.
    5. Keep Global Configuration rewriting off until a homepage request returns 200 with the fixed file in place.

    Frequently asked questions

    Why do I get a Joomla 500 error when I enable mod_rewrite?

    Apache is rejecting a directive in .htaccess, most often Options +FollowSymLinks, or mod_rewrite is not allowed. Check the error log, then comment FollowSymLinks and confirm AllowOverride.

    Is the administrator also down during a rewrite 500?

    Not always. /administrator/ can still load while the public site 500s. That pattern strongly points at front-end rewrite rules rather than a total PHP crash.

    Should I delete .htaccess permanently?

    No. Use a rename only to diagnose. Joomla needs a valid .htaccess for clean SEF URLs and basic exploit blocking from the core template.

    Does this apply to Joomla 5 and Joomla 6?

    Yes. The SEF and htaccess.txt flow is the same family on Joomla 4, 5, and 6. Always copy htaccess.txt from your exact version package.

    What if I am on Nginx?

    Do not chase mod_rewrite. Configure Nginx try_files $uri $uri/ /index.php?$args; (or your host’s Joomla snippet) instead of Apache .htaccess.

    Can a plugin cause a rewrite 500?

    Yes. Security and SEF extensions sometimes append invalid rules. Disable recent extensions, restore the core SEF block, then re-add custom rules one by one.

    Where can I get a clean Joomla htaccess file?

    From the htaccess.txt in your Joomla root or install package. Our htaccess for Joomla article covers version-specific notes and hardening.