Improved Statistical Methods for Financial Audit Manual Section 450: A Corrected Approach to Internal Control Testing

Author

Wade K. Copeland

Published

December 17, 2025

Introduction

An internal control is defined as a process effected by an entity’s oversight body, management, and other personnel, designed to provide reasonable assurance that the objectives of an entity will be achieved (U.S. Government Accountability Office 2025b, 6). The goal of an auditor is to obtain sufficient appropriate audit evidence about the operating effectiveness of relevant internal controls (U.S. Government Accountability Office 2025a, sec. 450.01).

Methods of the Financial Audit Manual Section 450

To determine the operating effectiveness of internal controls, auditors have relied on Figure 450.1 of the Financial Audit Manual Volume 1 (U.S. Government Accountability Office 2025a, sec. 450.09). This table provides the sample size and number of allowed deviations, before which an auditor can declare that the controls are effective. Written in terms of statistical hypothesis testing, we have the following null and alternative hypotheses, respectively:

  • H_0: The internal controls are ineffective, e.g., the population deviation rate is greater than or equal to some a priori specified tolerable rate.
  • H_a: The internal controls are effective, e.g., the population deviation rate is less than the tolerable rate.

Figure 450.1 from the FAM 450 indicates that with a sample size of 45, if an auditor observes zero deviations, they can reject with 90% confidence the null hypothesis that the population deviation rate is greater than the tolerable rate of 5%, and declare the controls effective. On the other hand, if an auditor observes even one deviation in the sample, they will fail to reject the null hypothesis that the controls are ineffective. This wording is very important because failing to reject the null hypothesis is not the same as being able to claim the controls are ineffective—an auditor who observes even one deviation cannot declare that the controls are ineffective. This is analogous to how courts declare someone not guilty due to lack of evidence, rather than declaring them innocent.

We can illustrate the inherent logical fallacy of declaring the controls ineffective using basic arithmetic. In the example above, declaring the controls ineffective means that we believe the tolerable rate of deviation is greater than 5% if 1/45 or approximately 2.2% of the controls failed. However, in order to say that the controls are ineffective at the 5% level we would need to observe at least more than that. As shown in the next section, an auditor will need 5/45 or 11.1% of controls to fail in order to claim they are ineffective at this level.

Updated Statistical Methods for the Financial Audit Manual Section 450

In practice, auditors are rarely interested in the above hypotheses and instead want to determine if there is enough evidence to conclude that the controls are ineffective. This requires reversing the hypotheses and adjusting the sample size calculations accordingly:

  • H_0: The internal controls are effective, e.g., the population deviation rate is less than or equal to the tolerable rate.
  • H_a: The internal controls are ineffective, e.g., the population deviation rate is greater than the tolerable rate.
Code
# This function returns the number of allowed deviations for tests of internal control effectiveness.
#
# Parameters:
#   - trd (double): Tolerable rate of deviation
#   - or (double): Overreliance, e.g., the probability of falsely rejecting a true null hypothesis
#   - n (integer): Sample size
#   - alt (character): The alternative hypothesis: (1) "less" corresponds to alternative that the controls are effective; (2) "greater" corresponds to the alternative that the controls are ineffective. 
#
# Returns:
#   - For the <= null hypothesis, this function returns the number of allowed deviations, after which the auditor will always fail to reject the null hypothesis that the controls are effective.  For the >= null hypothesis, this function returns the number of deviations after which the auditor will always reject the null hypothesis that the controls are effective.
binomDeviations <- function(trd, or, n, alt) {
    if(!(alt %in% c("less", "greater"))) stop("The parameter value for alt should be equal to 'less' or 'greater'")
    
    binomTests <- data.frame(successes = 1:n, pval = NA)
    for(i in 1:dim(binomTests)[1]) {
        binomTest <- binom.test(x = i, n = n, p = trd, alternative = alt, conf.level = 1 - or)
        binomTests[i, "pval"] <- binomTest$p.value
    }
    
    if(alt == "less") {
        expDev <- suppressWarnings(max(which(binomTests$pval < or)))
        if(is.infinite(expDev)) expDev = 0
    }

    if(alt == "greater") expDev <- suppressWarnings(min(which(binomTests$pval < or))) - 1
    
    return(as.integer(expDev))
}

# Construct the updated table
library("kableExtra")

trdTableRow <- function(n) {
    res = c(n, binomDeviations(trd = 0.05, or = 0.1, n = n, alt = "greater"), n, binomDeviations(trd = 0.1, or = 0.1, n = n, alt = "greater"))
    return(res)
}

tab = data.frame(rbind(trdTableRow(45), trdTableRow(78), trdTableRow(105), trdTableRow(132), trdTableRow(158)))

colnames(tab) <- c("Sample size", "Acceptable Number of Deviations", "Sample Size", "Acceptable Number of Deviations")

tab %>% 
    kbl(escape = FALSE, caption = "The number of allowed deviations after which an auditor has enough evidence to determine the internal controls are ineffective.") %>% 
    add_header_above(c("Tolerable Rate of Deviation 5%" = 2, "Tolerable Rate of Deviation 10%" = 2)) %>%
    add_header_above(c("90 Percent Confidence Level" = 4))
The number of allowed deviations after which an auditor has enough evidence to determine the internal controls are ineffective.
90 Percent Confidence Level
Tolerable Rate of Deviation 5%
Tolerable Rate of Deviation 10%
Sample size Acceptable Number of Deviations Sample Size Acceptable Number of Deviations
45 4 45 7
78 6 78 11
105 8 105 15
132 10 132 18
158 11 158 21

For the updated table, we use an exact test of binomial proportions to determine the number of allowed deviations before we can reject the null hypothesis that the true tolerable rate of deviation is less than or equal to the specified threshold (Rosner 2016, 252–53). The algorithm works as follows, given the hypothesized tolerable rate of deviation p, the sample size n, and the confidence level c:

  1. Let i be the number of observed deviations.
  2. Under the null hypothesis that \frac{i}{n} \le p, we calculate the probability of observing \frac{i}{n} or more extreme, also called the p-value.
  3. If the calculated p-value is less than 1-c, we reject the null hypothesis in favor of the alternative that \frac{i}{n} > p.
  4. The number of allowed deviations is the value i-1 such that if we observe this number of deviations or fewer, we will always fail to reject the null hypothesis.

These methods can be analogously applied to reproduce the original results in Figure 450.1, providing confirmation that the statistical methods used here are accurate. This validation is particularly important since the statistical methods underlying FAM 450 are not otherwise documented in the manual. Furthermore, this means that I have proven that any claim based on Figure 450.1 in FAM 450 that an audit client’s controls are ineffective, such as in U.S. Government Accountability Office (2025a), sections 450.17 and 450.18, is wrong.

R Session Information

All of the files needed to reproduce these results can be downloaded from the Git repository https://github.com/wkingc/fam450-corrected-r/.

Code
sessionInfo()
R version 4.5.1 (2025-06-13)
Platform: aarch64-apple-darwin24.4.0
Running under: macOS Tahoe 26.1

Matrix products: default
BLAS:   /opt/homebrew/Cellar/openblas/0.3.30/lib/libopenblasp-r0.3.30.dylib 
LAPACK: /opt/homebrew/Cellar/r/4.5.1/lib/R/lib/libRlapack.dylib;  LAPACK version 3.12.1

locale:
[1] C.UTF-8/C.UTF-8/C.UTF-8/C/C.UTF-8/C.UTF-8

time zone: America/New_York
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices datasets  utils     methods   base     

other attached packages:
[1] kableExtra_1.4.0

loaded via a namespace (and not attached):
 [1] svglite_2.2.1      cli_3.6.5          knitr_1.50         rlang_1.1.6       
 [5] xfun_0.53          stringi_1.8.7      renv_1.1.5         textshaping_1.0.4 
 [9] jsonlite_2.0.0     glue_1.8.0         htmltools_0.5.8.1  scales_1.4.0      
[13] rmarkdown_2.30     evaluate_1.0.5     fastmap_1.2.0      yaml_2.3.10       
[17] lifecycle_1.0.4    stringr_1.5.2      compiler_4.5.1     RColorBrewer_1.1-3
[21] rstudioapi_0.17.1  systemfonts_1.3.1  farver_2.1.2       digest_0.6.37     
[25] viridisLite_0.4.2  R6_2.6.1           magrittr_2.0.4     tools_4.5.1       
[29] xml2_1.4.0        

References

Rosner, Bernard. 2016. Fundamentals of Biostatistics. 8th ed. Boston, MA: Cengage Learning.
U.S. Government Accountability Office. 2025a. Financial Audit Manual Volume 1.” https://www.gao.gov/products/gao-25-107705.
———. 2025b. Standards for Internal Control in the Federal Government.” https://www.gao.gov/products/gao-25-107721.