New in BIG-IP version 11.1 are iFiles, a feature that allows users to load files through tmsh or the GUI onto the BIG-IP which can be referenced from iRules. This has an immediate use case of supplanting several of our codeshare entries for sorry and/or maintenance pages delivered directly from the BIG-IP instead of redirecting to a server to handle those requests. In this tech tip, I’ll cover the command options, the GUI configuration, and finally offer up a maintenance page iRule referencing iFiles.

Planning the Maintenance Page

When serving up html pages from an iRule in a variable or a data-group, several things, such as encoding images and escaping special characters to prevent Tcl errors or unfortunate interpretations, must be considered. With iFiles, however, much (and potentially all) of that trouble is eliminated. For this maintenance page, I want to return an HTML5 canvas bouncing F5 ball (original script source can be found here at to distract users during maintenance. So I’ll need two files, one image file for the F5 bouncing ball, and one text file for the html elements. The html text I’m using is below:

        var surface;
        var happy;
        var x = 50;
        var y = 0;
        var dirX = 1;
        var dirY = 1;

        function drawCanvas() {
            // Get our Canvas element
            surface = document.getElementById("myCanvas");
            if (surface.getContext) {
                // If Canvas is supported, load the image
                happy = new Image();
                happy.onload = loadingComplete;
                happy.src = "f5b_mini.png";

        function loadingComplete(e) {
            // When the image has loaded begin the loop
            setInterval(loop, 15);

        function loop() {
            // Each loop we move the image by altering its x/y position
            // Grab the context
            var surfaceContext = surface.getContext('2d');
            // Draw the image
            surfaceContext.drawImage(happy, x, y);

            x += dirX;
            y += dirY;

            if (x <= 0 || x > 500 - 18) {
                dirX = -dirX;
            if (y <= 0 || y > 250 - 28) {
                dirY = -dirY;

<body onload="drawCanvas();">
    <h1>Hey there...</h1><br>
    <h2>Relax and be mesmerized by the F5 ball as we make some changes</h2><br>
        <canvas id="myCanvas" width="500" height="250">
            <p>Your browser doesn't support canvas.</p>
    <h2>We'll be back online shortly...the DevCentral team</h2>

Creating the iFiles

Now that my page is ready, I can upload the files. This is done in System->File Management->iFile List->Import:



A couple quick notes on importing files. First, iFiles maximum size is 4M. Second, it’s probably a good idea to adopt a naming standard early in use of iFiles. I’m using <app_function|name_type>, but whatever works, right? Now that the files are on the system (default location: /config/filestore/files_d/Common_d/ifile_d), I need to create a reference for each of them under Local Traffic->iRules->iFile List. I’m just repeating the name I used for the iFile itself:



The iFile Command Syntax

The complete syntax for the iFile command is below. For details on each command, please visit the iFile wiki page.

ifile get <iFile Name>
ifile listall
ifile attributes <iFile Name>
ifile size <iFile Name>
ifile last_updated_by <iFile Name>
ifile last_update_time <iFile Name>
ifile revision <iFile Name>
ifile checksum <iFile Name>
array set <variable> [ifile attributes <iFile Name>]

Creating the iRule

Obviously the logic to serve up the maintenance page would need to be adjusted for a production environment, but for this example I’m just doing an HTTP::respond if the URL is “/”, and then I need a condition for the image as well. So what used to be a lot more work with encoding images and massaging javascript, with iFiles, I can just return the contents with no concerns utilizing the [ifile get <iFile Name>] command. It really is that simple.

    if { [HTTP::uri] eq "/" } {
        HTTP::respond 200 content [ifile get testapp_index_txt]
    } elseif { [HTTP::uri] eq "/f5b_mini.png" } {
        HTTP::respond 200 content [ifile get testapp_f5ball_img]
    } else { discard }

Browsing to the virtual results in this page:



I highlighted the maintenance page use case, but data served from external files will be useful for a large number of scenarios. Happy coding with the new iFiles feature delivered in BIG-IP v11.1.

Comments on this Article
Comment made 03-Jan-2012 by GavinW 156
Hi there,

Just a quick one hopefully... What are the benefits of using iFiles over the 'External files' functionality?

Comment made 03-Jan-2012 by Jason Rahm
iFiles are external files that are brought into the iRules fold, so to speak. The benefit of using them over encoding files into datagroups is simplification and efficiency.
Comment made 13-Jan-2012 by hoolio
"What are the benefits of using iFiles over the 'External files' functionality?"

iFiles are best suited for loading static content into LTM memory. Data groups offer better querying support using the class command. You have the same functionality for retrieving the source file for an external data group as you do with an iFile.

Comment made 21-Feb-2012 by Richard Jones 134
Is there any way to get the contents of an iFile via TMSH? I'm trying to pull iFile data using an iApp and can't figure it out. Thanks!

Comment made 24-Aug-2012 by Jie 2732
There seems to be a limit of 3852 bytes to the size of the html page using ifile to serv e cotent this way. Can anyone confirm this?
Comment made 27-Aug-2012 by hoolio
Hi Jie,

Yes, iFiles are limited to 4Mb currently. We're tracking a request to make this user-configurable in BZ385237. You can open a case with F5 Support to add your request to this request for enhancement.

Thanks, Aaron
Comment made 27-Aug-2012 by Jason Rahm
iFile limit is 4M
Comment made 27-Aug-2012 by hoolio
Also, if you have over 4Mb of content you want to serve, you could save them to multiple data groups and then concatenate them in the response

HTTP::respond 200 content "[ifile get ifile1][ifile get ifile2]"

Comment made 13-Sep-2013 by elastic 100
I am trying to use the iFiles to do a maintenance page, but I don't want to do a redirect to /maintenance/index.html, I just want to do an HTTP response 200, but using the suggestion from Aaron, of
HTTP::respond 200 content "[ifile get ifile1][ifile get ifile2]"

This simply displays the first file, then the second, basically as concatenated text files(does the same with gif's). I have an index.thml, a css and several gifs. Any ideas on how to display that via iFiles?
Comment made 13-Sep-2013 by Jason Rahm
you can concatenate the files, but if you want to render properly in the browser, you'll need to send a single text-based html page, use a redirect for the objects, or specify the object locations in the file you send via HTTP::respond and then serve them up individually from iFiles.
Comment made 18-Sep-2013 by Lyle 0
Trying to plan to combine ifile/irule approach with the "fallback host" uri feature. To avoid having to add/extend irules on existing virtual servers wondering if the following would work.

Create a single extra virtual server "maintpage" with no pool members, and an always available state (no health check?), and put the simple irule to server up the ifile always.

Then use the fallback host setting in the http profile(s), to send the to maintpage server. Thoughts ?
Comment made 18-Sep-2013 by Jason Rahm
that would work fine as long as you're ok with burning the extra IP address.
Comment made 10-Oct-2013 by Matt Watson 0
Thanks! Worked great!
Comment made 12-Nov-2013 by The Notorious BIGIP 18

Are iFile loaded into memory when the config is compiled or are iFiles always read from disk when called?


Comment made 12-Nov-2013 by Jason Rahm
iFiles in the system menu are disk only. Once you add one to the iRules iFiles list, however, they do sit in memory at load time.
Comment made 12-Jun-2014 by Drew 16
Hi Jason

Hopefully using iFiles will avoid our "multpiple redirect" headaches when serving maintenance pages now.


Comment made 22-Apr-2015 by Robert 534
I like this!!!
Comment made 11-May-2015 by sandevsingh 268
Awesome stuff Jason, I need some help in getting an irule for this. Aim is to get the sample ifile "helloworld" triggered when the active pool members is < 1. I created the following irule - when HTTP_REQUEST { if { [active_members [LB::server pool]] < 1 } { HTTP::respond 200 content [ifile get helloworld] } else { discard } } It is working fine when all the members of a pool are down, BUT when they are up I do not get any response back from the VS. Can you please advise?
Comment made 25-Jun-2015 by TJ Vreugdenhil 494
To " sandevsingh" remove your else discard statement.
Comment made 07-Jul-2015 by Ganesh Garg 268
Is it possible to get 2 Ifiles with HTTP_REQUEST { if { [active_members [LB::server pool]] < 1 } { HTTP::respond 200 content [ifile get helloworld] } } I am trying to put a image in second file, but that is not working properly..
Comment made 04-Sep-2015 by jothman-galec 2
how can i do the same fo big ip LTM version 10x ?
Comment made 03-Feb-2016 by DushyantSingh 135
Is there a way to associate 3 image files with one HTML and call them in the even of HTTP_REQUEST { if { [active_members [LB::server pool]] < 1 }. The image files are basically used for 3 different size of web browser depending upon device is being used.
Comment made 18-Feb-2016 by Piotr Lewandowski 1162
Hi DushyantSingh, I assume that you can do that using switch, tested and working on my side: switch [string tolower [HTTP::uri]] { "/" { HTTP::respond 200 content [ifile get main_maint_few_images_txt] } "/f5b_mini.png" { HTTP::respond 200 content [ifile get main_maint_png] } "/pic_mountain.jpg" { HTTP::respond 200 content [ifile get main_maint_02_jpg] } default { discard } }
Comment made 18-Feb-2016 by Piotr Lewandowski 1162
Of course you will have to detect device type as well but the basic idea of switch still works. Piotr
Comment made 31-Aug-2017 by Frank 270

I know this post is old !!! Don't know if this still the best way to redirect queries to a maintenance page if no pool member is available. Actually, I want to do this on GTM itself, if none of the pool VS is available in a pool (means if both VS is down in both DC's) i want to redirect queries to a maintenance page hosted locally on a f5 GTM. What will be the change is iRule? or any other change required in above article. Currently i am running version 11.5.3 on GTM and LTM